2 * Copyright (C) 2005-2008 Team XBMC
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)
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.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "GUIUserMessages.h"
23 #include "GUIWindowVideoNav.h"
24 #include "music/windows/GUIWindowMusicNav.h"
25 #include "utils/FileUtils.h"
27 #include "utils/RegExp.h"
28 #include "PlayListPlayer.h"
29 #include "GUIPassword.h"
30 #include "dialogs/GUIDialogFileBrowser.h"
31 #include "filesystem/VideoDatabaseDirectory.h"
32 #include "playlists/PlayListFactory.h"
33 #include "video/dialogs/GUIDialogVideoScan.h"
34 #include "dialogs/GUIDialogOK.h"
35 #include "addons/AddonManager.h"
36 #include "PartyModeManager.h"
37 #include "music/MusicDatabase.h"
38 #include "guilib/GUIWindowManager.h"
39 #include "dialogs/GUIDialogYesNo.h"
40 #include "dialogs/GUIDialogSelect.h"
41 #include "filesystem/Directory.h"
42 #include "filesystem/File.h"
44 #include "Application.h"
45 #include "settings/Settings.h"
46 #include "settings/AdvancedSettings.h"
47 #include "settings/GUISettings.h"
48 #include "guilib/LocalizeStrings.h"
49 #include "storage/MediaManager.h"
50 #include "utils/log.h"
51 #include "utils/URIUtils.h"
52 #include "TextureCache.h"
54 using namespace XFILE;
55 using namespace VIDEODATABASEDIRECTORY;
58 #define CONTROL_BTNVIEWASICONS 2
59 #define CONTROL_BTNSORTBY 3
60 #define CONTROL_BTNSORTASC 4
61 #define CONTROL_BTNTYPE 5
62 #define CONTROL_BTNSEARCH 8
63 #define CONTROL_LABELFILES 12
65 #define CONTROL_BTN_FILTER 19
66 #define CONTROL_BTNSHOWMODE 10
67 #define CONTROL_BTNSHOWALL 14
68 #define CONTROL_UNLOCK 11
70 #define CONTROL_FILTER 15
71 #define CONTROL_BTNPARTYMODE 16
72 #define CONTROL_BTNFLATTEN 17
73 #define CONTROL_LABELEMPTY 18
75 CGUIWindowVideoNav::CGUIWindowVideoNav(void)
76 : CGUIWindowVideoBase(WINDOW_VIDEO_NAV, "MyVideoNav.xml")
78 m_thumbLoader.SetObserver(this);
81 CGUIWindowVideoNav::~CGUIWindowVideoNav(void)
85 bool CGUIWindowVideoNav::OnAction(const CAction &action)
87 if (action.GetID() == ACTION_TOGGLE_WATCHED)
89 CFileItemPtr pItem = m_vecItems->Get(m_viewControl.GetSelectedItem());
90 if (pItem->IsParentFolder())
92 if (pItem && pItem->GetVideoInfoTag()->m_playCount == 0)
93 return OnContextButton(m_viewControl.GetSelectedItem(),CONTEXT_BUTTON_MARK_WATCHED);
94 if (pItem && pItem->GetVideoInfoTag()->m_playCount > 0)
95 return OnContextButton(m_viewControl.GetSelectedItem(),CONTEXT_BUTTON_MARK_UNWATCHED);
97 return CGUIWindowVideoBase::OnAction(action);
100 bool CGUIWindowVideoNav::OnMessage(CGUIMessage& message)
102 switch (message.GetMessage())
104 case GUI_MSG_WINDOW_RESET:
105 m_vecItems->m_strPath.clear();
107 case GUI_MSG_WINDOW_DEINIT:
108 if (m_thumbLoader.IsLoading())
109 m_thumbLoader.StopThread();
111 case GUI_MSG_WINDOW_INIT:
113 /* We don't want to show Autosourced items (ie removable pendrives, memorycards) in Library mode */
114 m_rootDir.AllowNonLocalSources(false);
116 SetProperty("flattened", g_settings.m_bMyVideoNavFlatten);
118 if (!CGUIWindowVideoBase::OnMessage(message))
121 // base class has opened the database, do our check
124 if (!m_database.HasContent() && m_vecItems->IsVideoDb())
125 { // no library - make sure we default to the root.
126 m_vecItems->m_strPath = "";
127 SetHistoryForPath("");
136 case GUI_MSG_CLICKED:
138 int iControl = message.GetSenderId();
139 if (iControl == CONTROL_BTNPARTYMODE)
141 if (g_partyModeManager.IsEnabled())
142 g_partyModeManager.Disable();
145 if (!g_partyModeManager.Enable(PARTYMODECONTEXT_VIDEO))
147 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE,false);
151 // Playlist directory is the root of the playlist window
152 if (m_guiState.get()) m_guiState->SetPlaylistDirectory("playlistvideo://");
159 if (iControl == CONTROL_BTNSEARCH)
163 else if (iControl == CONTROL_BTNSHOWMODE)
165 g_settings.CycleWatchMode(m_vecItems->GetContent());
168 // TODO: Can we perhaps filter this directly? Probably not for some of the more complicated views,
169 // but for those perhaps we can just display them all, and only filter when we get a list
171 Update(m_vecItems->m_strPath);
174 else if (iControl == CONTROL_BTNFLATTEN)
176 g_settings.m_bMyVideoNavFlatten = !g_settings.m_bMyVideoNavFlatten;
178 SetProperty("flattened", g_settings.m_bMyVideoNavFlatten);
179 CUtil::DeleteVideoDatabaseDirectoryCache();
184 else if (iControl == CONTROL_BTNSHOWALL)
186 if (g_settings.GetWatchMode(m_vecItems->GetContent()) == VIDEO_SHOW_ALL)
187 g_settings.SetWatchMode(m_vecItems->GetContent(), VIDEO_SHOW_UNWATCHED);
189 g_settings.SetWatchMode(m_vecItems->GetContent(), VIDEO_SHOW_ALL);
191 // TODO: Can we perhaps filter this directly? Probably not for some of the more complicated views,
192 // but for those perhaps we can just display them all, and only filter when we get a list
194 Update(m_vecItems->m_strPath);
199 // update the display
200 case GUI_MSG_SCAN_FINISHED:
201 case GUI_MSG_REFRESH_THUMBS:
203 Update(m_vecItems->m_strPath);
207 return CGUIWindowVideoBase::OnMessage(message);
210 CStdString CGUIWindowVideoNav::GetQuickpathName(const CStdString& strPath) const
212 if (strPath.Equals("videodb://1/1/"))
213 return "MovieGenres";
214 else if (strPath.Equals("videodb://1/2/"))
215 return "MovieTitles";
216 else if (strPath.Equals("videodb://1/3/"))
218 else if (strPath.Equals("videodb://1/4/"))
219 return "MovieActors";
220 else if (strPath.Equals("videodb://1/5/"))
221 return "MovieDirectors";
222 else if (strPath.Equals("videodb://1/"))
224 else if (strPath.Equals("videodb://2/1/"))
225 return "TvShowGenres";
226 else if (strPath.Equals("videodb://2/2/"))
227 return "TvShowTitles";
228 else if (strPath.Equals("videodb://2/3/"))
229 return "TvShowYears";
230 else if (strPath.Equals("videodb://2/4/"))
231 return "TvShowActors";
232 else if (strPath.Equals("videodb://2/"))
234 else if (strPath.Equals("videodb://3/1/"))
235 return "MusicVideoGenres";
236 else if (strPath.Equals("videodb://3/2/"))
237 return "MusicVideoTitles";
238 else if (strPath.Equals("videodb://3/3/"))
239 return "MusicVideoYears";
240 else if (strPath.Equals("videodb://3/4/"))
241 return "MusicVideoArtists";
242 else if (strPath.Equals("videodb://3/5/"))
243 return "MusicVideoDirectors";
244 else if (strPath.Equals("videodb://3/"))
245 return "MusicVideos";
246 else if (strPath.Equals("videodb://4/"))
247 return "RecentlyAddedMovies";
248 else if (strPath.Equals("videodb://5/"))
249 return "RecentlyAddedEpisodes";
250 else if (strPath.Equals("videodb://6/"))
251 return "RecentlyAddedMusicVideos";
252 else if (strPath.Equals("special://videoplaylists/"))
254 else if (strPath.Equals("sources://video/"))
258 CLog::Log(LOGERROR, " CGUIWindowVideoNav::GetQuickpathName: Unknown parameter (%s)", strPath.c_str());
263 void CGUIWindowVideoNav::OnItemLoaded(CFileItem* pItem)
265 /* even though the background loader is running multiple threads and we could,
266 be acting on someone else's flag, we don't care who invalidates the cache
267 only that it is done. We also don't care if it is done multiple times due
268 to a race between multiple threads here at the same time */
269 CUtil::DeleteVideoDatabaseDirectoryCache();
272 bool CGUIWindowVideoNav::GetDirectory(const CStdString &strDirectory, CFileItemList &items)
274 CFileItem directory(strDirectory, true);
276 if (m_thumbLoader.IsLoading())
277 m_thumbLoader.StopThread();
279 m_rootDir.SetCacheDirectory(DIR_CACHE_NEVER);
280 items.ClearProperties();
282 bool bResult = CGUIWindowVideoBase::GetDirectory(strDirectory, items);
285 if (items.IsVideoDb())
287 XFILE::CVideoDatabaseDirectory dir;
289 dir.GetQueryParams(items.m_strPath,params);
290 VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(items.m_strPath);
292 items.SetThumbnailImage("");
293 if (node == VIDEODATABASEDIRECTORY::NODE_TYPE_EPISODES ||
294 node == NODE_TYPE_SEASONS ||
295 node == NODE_TYPE_RECENTLY_ADDED_EPISODES)
297 CLog::Log(LOGDEBUG, "WindowVideoNav::GetDirectory");
298 // grab the show thumb
300 m_database.GetFilePathById(params.GetTvShowId(),showItem.m_strPath,VIDEODB_CONTENT_TVSHOWS);
301 showItem.SetVideoThumb();
302 items.SetProperty("tvshowthumb", showItem.GetThumbnailImage());
304 CVideoInfoTag details;
305 m_database.GetTvShowInfo(showItem.m_strPath, details, params.GetTvShowId());
306 items.SetProperty("fanart_color1", details.m_fanart.GetColor(0));
307 items.SetProperty("fanart_color2", details.m_fanart.GetColor(1));
308 items.SetProperty("fanart_color3", details.m_fanart.GetColor(2));
309 if (showItem.CacheLocalFanart())
310 items.SetProperty("fanart_image", showItem.GetCachedFanart());
312 // save the show description (showplot)
313 items.SetProperty("showplot", details.m_strPlot);
315 // set the season thumb
317 if (params.GetSeason() == 0)
318 strLabel = g_localizeStrings.Get(20381);
320 strLabel.Format(g_localizeStrings.Get(20358), params.GetSeason());
322 CFileItem item(strLabel);
323 URIUtils::GetParentPath(items.m_strPath,item.m_strPath);
324 item.m_bIsFolder = true;
325 item.SetCachedSeasonThumb();
326 if (item.HasThumbnail())
327 items.SetProperty("seasonthumb",item.GetThumbnailImage());
329 // the container folder thumb is the parent (i.e. season or show)
330 if (node == NODE_TYPE_EPISODES || node == NODE_TYPE_RECENTLY_ADDED_EPISODES)
332 items.SetContent("episodes");
333 // grab the season thumb as the folder thumb
336 if (params.GetSeason() == -1 && items.Size() > 0)
338 CQueryParams params2;
339 dir.GetQueryParams(items[0]->m_strPath,params2);
340 strLabel.Format(g_localizeStrings.Get(20358), params2.GetSeason());
341 URIUtils::GetParentPath(items.m_strPath,strPath);
345 if (params.GetSeason() == 0)
346 strLabel = g_localizeStrings.Get(20381);
348 strLabel.Format(g_localizeStrings.Get(20358), params.GetSeason());
349 strPath = items.m_strPath;
352 CFileItem item(strLabel);
353 item.m_strPath = strPath;
354 item.m_bIsFolder = true;
355 item.GetVideoInfoTag()->m_strPath = showItem.m_strPath;
356 item.SetCachedSeasonThumb();
358 items.SetThumbnailImage(item.GetThumbnailImage());
359 items.SetProperty("seasonthumb",item.GetThumbnailImage());
363 items.SetContent("seasons");
364 items.SetThumbnailImage(showItem.GetThumbnailImage());
367 else if (node == NODE_TYPE_TITLE_MOVIES ||
368 node == NODE_TYPE_RECENTLY_ADDED_MOVIES)
369 items.SetContent("movies");
370 else if (node == NODE_TYPE_TITLE_TVSHOWS)
371 items.SetContent("tvshows");
372 else if (node == NODE_TYPE_TITLE_MUSICVIDEOS ||
373 node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
374 items.SetContent("musicvideos");
375 else if (node == NODE_TYPE_GENRE)
376 items.SetContent("genres");
377 else if (node == NODE_TYPE_COUNTRY)
378 items.SetContent("countries");
379 else if (node == NODE_TYPE_ACTOR)
381 if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
382 items.SetContent("artists");
384 items.SetContent("actors");
386 else if (node == NODE_TYPE_DIRECTOR)
387 items.SetContent("directors");
388 else if (node == NODE_TYPE_STUDIO)
389 items.SetContent("studios");
390 else if (node == NODE_TYPE_YEAR)
391 items.SetContent("years");
392 else if (node == NODE_TYPE_MUSICVIDEOS_ALBUM)
393 items.SetContent("albums");
395 items.SetContent("");
398 { // load info from the database
399 LoadVideoInfo(items);
405 void CGUIWindowVideoNav::LoadVideoInfo(CFileItemList &items)
407 // TODO: this could possibly be threaded as per the music info loading,
408 // we could also cache the info
409 CStdString content = m_database.GetContentForPath(items.m_strPath);
410 items.SetContent(content);
411 if (!content.IsEmpty())
413 for (int i = 0; i < items.Size(); i++)
415 CFileItemPtr pItem = items[i];
417 if (m_database.GetItemForPath(content, pItem->m_strPath, item))
418 { // copy info across
419 pItem->UpdateInfo(item);
420 // TODO: we may wish to use a playable_url parameter here rather than
421 // switching the path of the item (eg movie as a folder)
422 pItem->m_strPath = item.m_strPath;
423 pItem->m_bIsFolder = item.m_bIsFolder;
429 for (int i = 0; i < items.Size(); i++)
431 CFileItemPtr pItem = items[i];
432 int playCount = m_database.GetPlayCount(*pItem);
434 pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, playCount > 0);
439 void CGUIWindowVideoNav::UpdateButtons()
441 CGUIWindowVideoBase::UpdateButtons();
443 // Update object count
444 int iItems = m_vecItems->Size();
447 // check for parent dir and "all" items
448 // should always be the first two items
449 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
451 CFileItemPtr pItem = m_vecItems->Get(i);
452 if (pItem->IsParentFolder()) iItems--;
453 if (pItem->m_strPath.Left(4).Equals("/-1/")) iItems--;
456 if (m_vecItems->Size() > 2 &&
457 m_vecItems->Get(m_vecItems->Size()-1)->m_strPath.Left(4).Equals("/-1/"))
461 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
462 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
464 // set the filter label
468 if (m_vecItems->m_strPath.Equals("special://videoplaylists/"))
469 strLabel = g_localizeStrings.Get(136);
471 else if (m_vecItems->IsPlayList())
473 // get playlist name from path
475 URIUtils::Split(m_vecItems->m_strPath, strDummy, strLabel);
477 else if (m_vecItems->m_strPath.Equals("sources://video/"))
478 strLabel = g_localizeStrings.Get(744);
479 // everything else is from a videodb:// path
480 else if (m_vecItems->IsVideoDb())
482 CVideoDatabaseDirectory dir;
483 dir.GetLabel(m_vecItems->m_strPath, strLabel);
486 strLabel = URIUtils::GetFileName(m_vecItems->m_strPath);
488 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
490 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
491 SET_CONTROL_LABEL(CONTROL_BTNSHOWMODE, g_localizeStrings.Get(16100 + watchMode));
493 SET_CONTROL_SELECTED(GetID(), CONTROL_BTNSHOWALL, watchMode != VIDEO_SHOW_ALL);
495 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
497 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNFLATTEN, g_settings.m_bMyVideoNavFlatten);
500 /// \brief Search for names, genres, artists, directors, and plots with search string \e strSearch in the
501 /// \brief video databases and return the found \e items
502 /// \param strSearch The search string
503 /// \param items Items Found
504 void CGUIWindowVideoNav::DoSearch(const CStdString& strSearch, CFileItemList& items)
506 CFileItemList tempItems;
507 CStdString strGenre = g_localizeStrings.Get(515); // Genre
508 CStdString strActor = g_localizeStrings.Get(20337); // Actor
509 CStdString strDirector = g_localizeStrings.Get(20339); // Director
510 CStdString strMovie = g_localizeStrings.Get(20338); // Movie
513 m_database.GetMoviesByName(strSearch, tempItems);
514 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20338) + "] ", items);
516 m_database.GetEpisodesByName(strSearch, tempItems);
517 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20359) + "] ", items);
519 m_database.GetTvShowsByName(strSearch, tempItems);
520 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20364) + "] ", items);
522 m_database.GetMusicVideosByName(strSearch, tempItems);
523 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20391) + "] ", items);
525 m_database.GetMusicVideosByAlbum(strSearch, tempItems);
526 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(558) + "] ", items);
528 // get matching genres
529 m_database.GetMovieGenresByName(strSearch, tempItems);
530 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20342) + "] ", items);
532 m_database.GetTvShowGenresByName(strSearch, tempItems);
533 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20343) + "] ", items);
535 m_database.GetMusicVideoGenresByName(strSearch, tempItems);
536 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20389) + "] ", items);
539 m_database.GetMovieActorsByName(strSearch, tempItems);
540 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20342) + "] ", items);
542 m_database.GetTvShowsActorsByName(strSearch, tempItems);
543 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20343) + "] ", items);
545 m_database.GetMusicVideoArtistsByName(strSearch, tempItems);
546 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20389) + "] ", items);
549 m_database.GetMovieDirectorsByName(strSearch, tempItems);
550 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20342) + "] ", items);
552 m_database.GetTvShowsDirectorsByName(strSearch, tempItems);
553 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20343) + "] ", items);
555 m_database.GetMusicVideoDirectorsByName(strSearch, tempItems);
556 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20389) + "] ", items);
559 m_database.GetEpisodesByPlot(strSearch, tempItems);
560 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20365) + "] ", items);
562 m_database.GetMoviesByPlot(strSearch, tempItems);
563 AppendAndClearSearchItems(tempItems, "[" + strMovie + " " + g_localizeStrings.Get(207) + "] ", items);
566 void CGUIWindowVideoNav::PlayItem(int iItem)
568 // unlike additemtoplaylist, we need to check the items here
569 // before calling it since the current playlist will be stopped
572 // root is not allowed
573 if (m_vecItems->IsVirtualDirectoryRoot())
576 CGUIWindowVideoBase::PlayItem(iItem);
579 void CGUIWindowVideoNav::OnInfo(CFileItem* pItem, ADDON::ScraperPtr& scraper)
581 m_database.Open(); // since we can be called from the music library without being inited
582 if (pItem->IsVideoDb())
583 scraper = m_database.GetScraperForPath(pItem->GetVideoInfoTag()->m_strPath);
586 CStdString strPath,strFile;
587 URIUtils::Split(pItem->m_strPath,strPath,strFile);
588 scraper = m_database.GetScraperForPath(strPath);
591 CGUIWindowVideoBase::OnInfo(pItem,scraper);
594 bool CGUIWindowVideoNav::CanDelete(const CStdString& strPath)
597 CVideoDatabaseDirectory::GetQueryParams(strPath,params);
599 if (params.GetMovieId() != -1 ||
600 params.GetEpisodeId() != -1 ||
601 params.GetMVideoId() != -1 ||
602 (params.GetTvShowId() != -1 && params.GetSeason() == -1
603 && !CVideoDatabaseDirectory::IsAllItem(strPath)))
609 void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
611 if (m_vecItems->IsParentFolder())
614 if (!m_vecItems->IsVideoDb())
616 if (!pItem->m_strPath.Equals("newsmartplaylist://video") &&
617 !pItem->m_strPath.Equals("special://videoplaylists/") &&
618 !pItem->m_strPath.Equals("sources://video/"))
619 CGUIWindowVideoBase::OnDeleteItem(pItem);
621 else if (pItem->m_strPath.Left(14).Equals("videodb://1/7/") &&
622 pItem->m_strPath.size() > 14 && pItem->m_bIsFolder)
624 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
625 pDialog->SetLine(0, g_localizeStrings.Get(432));
627 strLabel.Format(g_localizeStrings.Get(433),pItem->GetLabel());
628 pDialog->SetLine(1, strLabel);
629 pDialog->SetLine(2, "");;
631 if (pDialog->IsConfirmed())
634 CDirectory::GetDirectory(pItem->m_strPath,items,"",false,false,DIR_CACHE_ONCE,true,true);
635 for (int i=0;i<items.Size();++i)
636 OnDeleteItem(items[i]);
638 CVideoDatabaseDirectory dir;
640 dir.GetQueryParams(pItem->m_strPath,params);
641 m_database.DeleteSet(params.GetSetId());
646 if (!DeleteItem(pItem.get()))
649 CStdString strDeletePath;
650 if (pItem->m_bIsFolder)
651 strDeletePath=pItem->GetVideoInfoTag()->m_strPath;
653 strDeletePath=pItem->GetVideoInfoTag()->m_strFileNameAndPath;
655 if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
657 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
658 if (strDeletePath.Right(9).Equals("VIDEO_TS/"))
660 URIUtils::RemoveSlashAtEnd(strDeletePath);
661 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
664 if (URIUtils::HasSlashAtEnd(strDeletePath))
665 pItem->m_bIsFolder=true;
667 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
668 CUtil::SupportsFileOperations(strDeletePath))
670 pItem->m_strPath = strDeletePath;
671 CGUIWindowVideoBase::OnDeleteItem(pItem);
675 CUtil::DeleteVideoDatabaseDirectoryCache();
678 bool CGUIWindowVideoNav::DeleteItem(CFileItem* pItem, bool bUnavailable /* = false */)
680 if (!pItem->HasVideoInfoTag() || !CanDelete(pItem->m_strPath))
683 VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES;
684 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty())
685 iType = VIDEODB_CONTENT_TVSHOWS;
686 if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iSeason > -1 && !pItem->m_bIsFolder)
687 iType = VIDEODB_CONTENT_EPISODES;
688 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strArtist.IsEmpty())
689 iType = VIDEODB_CONTENT_MUSICVIDEOS;
691 // dont allow update while scanning
692 CGUIDialogVideoScan* pDialogScan = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
693 if (pDialogScan && pDialogScan->IsScanning())
695 CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
700 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
703 if (iType == VIDEODB_CONTENT_MOVIES)
704 pDialog->SetHeading(432);
705 if (iType == VIDEODB_CONTENT_EPISODES)
706 pDialog->SetHeading(20362);
707 if (iType == VIDEODB_CONTENT_TVSHOWS)
708 pDialog->SetHeading(20363);
709 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
710 pDialog->SetHeading(20392);
714 pDialog->SetLine(0, g_localizeStrings.Get(662));
715 pDialog->SetLine(1, g_localizeStrings.Get(663));
716 pDialog->SetLine(2, "");;
722 strLine.Format(g_localizeStrings.Get(433),pItem->GetLabel());
723 pDialog->SetLine(0, strLine);
724 pDialog->SetLine(1, "");
725 pDialog->SetLine(2, "");;
729 if (!pDialog->IsConfirmed())
733 CVideoDatabase database;
736 database.GetFilePathById(pItem->GetVideoInfoTag()->m_iDbId, path, iType);
739 if (iType == VIDEODB_CONTENT_MOVIES)
740 database.DeleteMovie(path);
741 if (iType == VIDEODB_CONTENT_EPISODES)
742 database.DeleteEpisode(path, pItem->GetVideoInfoTag()->m_iDbId);
743 if (iType == VIDEODB_CONTENT_TVSHOWS)
744 database.DeleteTvShow(path);
745 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
746 database.DeleteMusicVideo(path);
748 if (iType == VIDEODB_CONTENT_TVSHOWS)
749 database.SetPathHash(path,"");
752 CStdString strDirectory;
753 URIUtils::GetDirectory(path,strDirectory);
754 database.SetPathHash(strDirectory,"");
760 void CGUIWindowVideoNav::OnPrepareFileItems(CFileItemList &items)
762 CGUIWindowVideoBase::OnPrepareFileItems(items);
766 CVideoDatabaseDirectory dir;
767 dir.GetQueryParams(items.m_strPath,params);
768 if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
769 CGUIWindowMusicNav::SetupFanart(items);
771 NODE_TYPE node = dir.GetDirectoryChildType(items.m_strPath);
773 // now filter as necessary
774 bool filterWatched=false;
775 if (node == NODE_TYPE_EPISODES
776 || node == NODE_TYPE_SEASONS
777 || node == NODE_TYPE_TITLE_MOVIES
778 || node == NODE_TYPE_TITLE_TVSHOWS
779 || node == NODE_TYPE_TITLE_MUSICVIDEOS
780 || node == NODE_TYPE_RECENTLY_ADDED_EPISODES
781 || node == NODE_TYPE_RECENTLY_ADDED_MOVIES
782 || node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
783 filterWatched = true;
784 if (!items.IsVideoDb())
785 filterWatched = true;
786 if (items.IsSmartPlayList() && items.GetContent() == "tvshows")
787 node = NODE_TYPE_TITLE_TVSHOWS; // so that the check below works
789 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
791 for (int i = 0; i < items.Size(); i++)
793 CFileItemPtr item = items.Get(i);
794 if(item->HasVideoInfoTag() && (node == NODE_TYPE_TITLE_TVSHOWS || node == NODE_TYPE_SEASONS))
796 if (watchMode == VIDEO_SHOW_UNWATCHED)
797 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("unwatchedepisodes");
798 if (watchMode == VIDEO_SHOW_WATCHED)
799 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("watchedepisodes");
800 item->SetProperty("numepisodes", item->GetVideoInfoTag()->m_iEpisode);
805 if((watchMode==VIDEO_SHOW_WATCHED && item->GetVideoInfoTag()->m_playCount== 0)
806 || (watchMode==VIDEO_SHOW_UNWATCHED && item->GetVideoInfoTag()->m_playCount > 0))
815 void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
818 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
819 item = m_vecItems->Get(itemNumber);
821 CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons);
823 if (item && item->GetPropertyBOOL("pluginreplacecontextitems"))
826 CVideoDatabaseDirectory dir;
827 NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->m_strPath);
831 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
832 if (pScanDlg && pScanDlg->IsScanning())
833 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
835 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
837 else if (m_vecItems->m_strPath.Equals("sources://video/"))
839 // get the usual shares
840 CGUIDialogContextMenu::GetContextButtons("video", item, buttons);
841 // add scan button somewhere here
842 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
843 if (pScanDlg && pScanDlg->IsScanning())
844 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning
845 if (!item->IsDVD() && item->m_strPath != "add" &&
846 (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
848 CVideoDatabase database;
850 ADDON::ScraperPtr info = database.GetScraperForPath(item->m_strPath);
852 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
854 if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
856 if (info && info->Content() != CONTENT_NONE)
857 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
859 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
863 if (info && (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning())))
864 buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
869 ADDON::ScraperPtr info;
870 VIDEO::SScanSettings settings;
871 GetScraperForItem(item.get(), info, settings);
873 if (info && info->Content() == CONTENT_TVSHOWS)
874 buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352);
875 else if (info && info->Content() == CONTENT_MUSICVIDEOS)
876 buttons.Add(CONTEXT_BUTTON_INFO,20393);
877 else if (!item->m_bIsFolder && !item->m_strPath.Left(19).Equals("newsmartplaylist://"))
878 buttons.Add(CONTEXT_BUTTON_INFO, 13346);
880 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strArtist.IsEmpty())
882 CMusicDatabase database;
884 if (database.GetArtistByName(item->GetVideoInfoTag()->m_strArtist) > -1)
885 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396);
887 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0)
889 CMusicDatabase database;
891 if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1)
892 buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397);
894 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 &&
895 item->GetVideoInfoTag()->m_strArtist.size() > 0 &&
896 item->GetVideoInfoTag()->m_strTitle.size() > 0)
898 CMusicDatabase database;
900 if (database.GetSongByArtistAndAlbumAndTitle(item->GetVideoInfoTag()->m_strArtist,
901 item->GetVideoInfoTag()->m_strAlbum,
902 item->GetVideoInfoTag()->m_strTitle) > -1)
904 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398);
907 if (!item->IsParentFolder())
909 // can we update the database?
910 if (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
912 if (node == NODE_TYPE_TITLE_TVSHOWS)
914 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
915 if (pScanDlg && pScanDlg->IsScanning())
916 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
918 buttons.Add(CONTEXT_BUTTON_UPDATE_TVSHOW, 13349);
920 if (!item->IsPlugin() && !item->IsLiveTV() && !item->IsAddonsPath() &&
921 item->m_strPath != "sources://video/" && item->m_strPath != "special://videoplaylists/")
923 if (item->m_bIsFolder)
925 // Have both options for folders since we don't know whether all childs are watched/unwatched
926 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
927 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
931 if (item->GetOverlayImage().Equals("OverlayWatched.png"))
932 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
934 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
937 if ((node == NODE_TYPE_TITLE_TVSHOWS) ||
938 (item->IsVideoDb() && item->HasVideoInfoTag() && !item->m_bIsFolder))
940 buttons.Add(CONTEXT_BUTTON_EDIT, 16105); //Edit Title
942 if (m_database.HasContent(VIDEODB_CONTENT_TVSHOWS) && item->HasVideoInfoTag() &&
943 !item->m_bIsFolder && item->GetVideoInfoTag()->m_iEpisode == -1 &&
944 item->GetVideoInfoTag()->m_strArtist.IsEmpty() && item->GetVideoInfoTag()->m_iDbId >= 0) // movie entry
946 if (m_database.IsLinkedToTvshow(item->GetVideoInfoTag()->m_iDbId))
947 buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE,20385);
948 buttons.Add(CONTEXT_BUTTON_LINK_MOVIE,20384);
951 if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
952 buttons.Add(CONTEXT_BUTTON_SET_SEASON_THUMB, 20371);
954 if (item->m_strPath.Left(14).Equals("videodb://1/7/") && item->m_strPath.size() > 14 && item->m_bIsFolder) // sets
956 buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
957 buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_THUMB, 20435);
958 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
961 if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder)
963 if (m_vecItems->m_strPath.Left(11).Equals("videodb://3")) // mvids
964 buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
966 buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
968 if (item->IsVideoDb() && item->HasVideoInfoTag() &&
969 (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS))
971 if (info && info->Content() == CONTENT_TVSHOWS)
973 if(item->GetVideoInfoTag()->m_iBookmarkId != -1 &&
974 item->GetVideoInfoTag()->m_iBookmarkId != 0)
976 buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
979 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
982 // this should ideally be non-contextual (though we need some context for non-tv show node I guess)
983 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
984 if (pScanDlg && pScanDlg->IsScanning())
986 if (node != NODE_TYPE_TITLE_TVSHOWS)
987 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
990 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
993 if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
994 { // non-video db items, file operations are allowed
995 if (!item->IsReadOnly())
997 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
998 buttons.Add(CONTEXT_BUTTON_RENAME, 118);
1000 // add "Set/Change content" to folders
1001 if (item->m_bIsFolder && !item->IsPlayList() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
1003 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1004 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
1006 if (info && info->Content() != CONTENT_NONE)
1007 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
1009 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
1013 if (item->IsPlugin() || item->m_strPath.Left(9).Equals("script://") || m_vecItems->IsPlugin())
1014 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
1017 CGUIWindowVideoBase::GetNonContextButtons(itemNumber, buttons);
1020 bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
1023 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
1024 item = m_vecItems->Get(itemNumber);
1025 if (CGUIDialogContextMenu::OnContextButton("video", item, button))
1027 //TODO should we search DB for entries from plugins?
1028 if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin()
1029 && !item->IsLiveTV() &&!item->IsRSS())
1031 OnUnAssignContent(item->m_strPath,20375,20340,20341);
1033 Update(m_vecItems->m_strPath);
1038 case CONTEXT_BUTTON_EDIT:
1039 UpdateVideoTitle(item.get());
1040 CUtil::DeleteVideoDatabaseDirectoryCache();
1041 Update(m_vecItems->m_strPath);
1044 case CONTEXT_BUTTON_SET_SEASON_THUMB:
1045 case CONTEXT_BUTTON_SET_ACTOR_THUMB:
1046 case CONTEXT_BUTTON_SET_ARTIST_THUMB:
1047 case CONTEXT_BUTTON_SET_MOVIESET_THUMB:
1049 // Grab the thumbnails from the web
1051 CFileItemList items;
1052 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,"imdbthumbs",strPath);
1053 CFileItemPtr cacheItem(new CFileItem(strPath,true));
1054 CFileUtils::DeleteItem(cacheItem,true);
1055 XFILE::CDirectory::Create(strPath);
1056 CFileItemPtr noneitem(new CFileItem("thumb://None", false));
1057 CStdString cachedThumb = m_vecItems->Get(itemNumber)->GetCachedSeasonThumb();
1058 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1059 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedActorThumb();
1060 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1061 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedArtistThumb();
1062 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1063 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedVideoThumb();
1064 if (CFile::Exists(cachedThumb))
1066 CFileItemPtr item(new CFileItem("thumb://Current", false));
1067 item->SetThumbnailImage(cachedThumb);
1068 item->SetLabel(g_localizeStrings.Get(20016));
1071 noneitem->SetIconImage("DefaultFolder.png");
1072 noneitem->SetLabel(g_localizeStrings.Get(20018));
1074 vector<CStdString> thumbs;
1075 if (button != CONTEXT_BUTTON_SET_ARTIST_THUMB)
1078 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1079 m_database.GetTvShowInfo("",tag,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId);
1081 tag = *m_vecItems->Get(itemNumber)->GetVideoInfoTag();
1082 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1083 tag.m_strPictureURL.GetThumbURLs(thumbs, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iSeason);
1085 tag.m_strPictureURL.GetThumbURLs(thumbs);
1087 for (unsigned int i = 0; i < thumbs.size(); i++)
1089 CStdString strItemPath;
1090 strItemPath.Format("thumb://Remote%i",i);
1091 CFileItemPtr item(new CFileItem(strItemPath, false));
1092 item->SetThumbnailImage(thumbs[i]);
1093 item->SetIconImage("DefaultPicture.png");
1094 item->SetLabel(g_localizeStrings.Get(20015));
1097 // TODO: Do we need to clear the cached image?
1098 // CTextureCache::Get().ClearCachedImage(thumbs[i]);
1103 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1105 CStdString picturePath;
1107 CStdString strPath = m_vecItems->Get(itemNumber)->m_strPath;
1108 URIUtils::RemoveSlashAtEnd(strPath);
1110 int nPos=strPath.ReverseFind("/");
1113 // try to guess where the user should start
1114 // browsing for the artist thumb
1115 CMusicDatabase database;
1117 long idArtist=database.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
1118 database.GetArtistPath(idArtist, picturePath);
1121 CStdString strThumb;
1122 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1123 if (XFILE::CFile::Exists(strThumb))
1125 CFileItemPtr pItem(new CFileItem(strThumb,false));
1126 pItem->SetLabel(g_localizeStrings.Get(20017));
1127 pItem->SetThumbnailImage(strThumb);
1132 noneitem->SetIconImage("DefaultArtist.png");
1135 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1137 CStdString picturePath;
1138 CStdString strThumb;
1139 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1140 if (XFILE::CFile::Exists(strThumb))
1142 CFileItemPtr pItem(new CFileItem(strThumb,false));
1143 pItem->SetLabel(g_localizeStrings.Get(20017));
1144 pItem->SetThumbnailImage(strThumb);
1149 noneitem->SetIconImage("DefaultActor.png");
1152 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1153 noneitem->SetIconImage("DefaultVideo.png");
1156 items.Add(noneitem);
1158 VECSOURCES sources=g_settings.m_videoSources;
1159 g_mediaManager.GetLocalDrives(sources);
1161 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources,
1162 g_localizeStrings.Get(20019), result))
1164 return false; // user cancelled
1167 if (result == "thumb://Current")
1168 return false; // user chose the one they have
1170 // delete the thumbnail if that's what the user wants, else overwrite with the
1172 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1173 if (result.Left(14) == "thumb://Remote")
1175 int number = atoi(result.Mid(14));
1176 CFile::Cache(thumbs[number], cachedThumb);
1178 if (result == "thumb://None")
1179 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1181 CFile::Cache(result,cachedThumb);
1183 CUtil::DeleteVideoDatabaseDirectoryCache();
1184 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
1185 g_windowManager.SendMessage(msg);
1186 Update(m_vecItems->m_strPath);
1190 case CONTEXT_BUTTON_UPDATE_LIBRARY:
1195 case CONTEXT_BUTTON_UNLINK_MOVIE:
1197 OnLinkMovieToTvShow(itemNumber, true);
1198 Update(m_vecItems->m_strPath);
1201 case CONTEXT_BUTTON_LINK_MOVIE:
1203 OnLinkMovieToTvShow(itemNumber, false);
1206 case CONTEXT_BUTTON_GO_TO_ARTIST:
1209 CMusicDatabase database;
1211 strPath.Format("musicdb://2/%ld/",database.GetArtistByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist));
1212 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1215 case CONTEXT_BUTTON_GO_TO_ALBUM:
1218 CMusicDatabase database;
1220 strPath.Format("musicdb://3/%ld/",database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum));
1221 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1224 case CONTEXT_BUTTON_PLAY_OTHER:
1226 CMusicDatabase database;
1229 if (database.GetSongById(database.GetSongByArtistAndAlbumAndTitle(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum,
1230 m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle),
1233 g_application.getApplicationMessenger().PlayFile(song);
1238 case CONTEXT_BUTTON_UNLINK_BOOKMARK:
1241 m_database.DeleteBookMarkForEpisode(*m_vecItems->Get(itemNumber)->GetVideoInfoTag());
1243 CUtil::DeleteVideoDatabaseDirectoryCache();
1244 Update(m_vecItems->m_strPath);
1252 return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
1255 void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove)
1261 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1263 for (unsigned int i=0;i<ids.size();++i)
1266 m_database.GetTvShowInfo("",tag,ids[i]);
1267 CFileItemPtr show(new CFileItem(tag));
1273 m_database.GetTvShowsNav("videodb://2/2",list);
1275 // remove already linked shows
1277 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1279 for (int i=0;i<list.Size();)
1282 for (j=0;j<ids.size();++j)
1284 if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j])
1287 if (j == ids.size())
1293 int iSelectedLabel = 0;
1294 if (list.Size() > 1)
1296 list.Sort(g_guiSettings.GetBool("filelists.ignorethewhensorting") ? SORT_METHOD_LABEL_IGNORE_THE : SORT_METHOD_LABEL, SORT_ORDER_ASC);
1297 CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
1299 pDialog->SetItems(&list);
1300 pDialog->SetHeading(20356);
1302 iSelectedLabel = pDialog->GetSelectedLabel();
1304 if (iSelectedLabel > -1)
1306 m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,
1307 list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove);
1308 CUtil::DeleteVideoDatabaseDirectoryCache();
1312 bool CGUIWindowVideoNav::OnClick(int iItem)
1314 CFileItemPtr item = m_vecItems->Get(iItem);
1315 if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
1317 if (!DeleteItem(item.get(), true))
1321 m_vecItems->RemoveDiscCache(GetID());
1322 Update(m_vecItems->m_strPath);
1323 m_viewControl.SetSelectedItem(iItem);
1327 return CGUIWindowVideoBase::OnClick(iItem);
1330 CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
1332 if (dir.Equals("MovieGenres"))
1333 return "videodb://1/1/";
1334 else if (dir.Equals("MovieTitles"))
1335 return "videodb://1/2/";
1336 else if (dir.Equals("MovieYears"))
1337 return "videodb://1/3/";
1338 else if (dir.Equals("MovieActors"))
1339 return "videodb://1/4/";
1340 else if (dir.Equals("MovieDirectors"))
1341 return "videodb://1/5/";
1342 else if (dir.Equals("MovieStudios"))
1343 return "videodb://1/6/";
1344 else if (dir.Equals("MovieSets"))
1345 return "videodb://1/7/";
1346 else if (dir.Equals("MovieCountries"))
1347 return "videodb://1/8/";
1348 else if (dir.Equals("Movies"))
1349 return "videodb://1/";
1350 else if (dir.Equals("TvShowGenres"))
1351 return "videodb://2/1/";
1352 else if (dir.Equals("TvShowTitles"))
1353 return "videodb://2/2/";
1354 else if (dir.Equals("TvShowYears"))
1355 return "videodb://2/3/";
1356 else if (dir.Equals("TvShowActors"))
1357 return "videodb://2/4/";
1358 else if (dir.Equals("TvShowStudios"))
1359 return "videodb://2/5/";
1360 else if (dir.Equals("TvShows"))
1361 return "videodb://2/";
1362 else if (dir.Equals("MusicVideoGenres"))
1363 return "videodb://3/1/";
1364 else if (dir.Equals("MusicVideoTitles"))
1365 return "videodb://3/2/";
1366 else if (dir.Equals("MusicVideoYears"))
1367 return "videodb://3/3/";
1368 else if (dir.Equals("MusicVideoArtists"))
1369 return "videodb://3/4/";
1370 else if (dir.Equals("MusicVideoDirectors"))
1371 return "videodb://3/5/";
1372 else if (dir.Equals("MusicVideoStudios"))
1373 return "videodb://3/6/";
1374 else if (dir.Equals("MusicVideos"))
1375 return "videodb://3/";
1376 else if (dir.Equals("RecentlyAddedMovies"))
1377 return "videodb://4/";
1378 else if (dir.Equals("RecentlyAddedEpisodes"))
1379 return "videodb://5/";
1380 else if (dir.Equals("RecentlyAddedMusicVideos"))
1381 return "videodb://6/";
1382 else if (dir.Equals("Files"))
1383 return "sources://video/";
1384 return CGUIWindowVideoBase::GetStartFolder(dir);