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 if (!items.GetContent().IsEmpty())
410 return; // don't load for listings that have content set
412 CStdString content = m_database.GetContentForPath(items.m_strPath);
413 if (content.IsEmpty())
415 items.SetContent("files");
418 items.SetContent(content);
420 bool clean = (g_guiSettings.GetBool("myvideos.cleanstrings") &&
421 !items.IsVirtualDirectoryRoot() &&
422 m_stackingAvailable);
424 if (!content.IsEmpty())
426 for (int i = 0; i < items.Size(); i++)
428 CFileItemPtr pItem = items[i];
430 if (m_database.GetItemForPath(content, pItem->m_strPath, item))
431 { // copy info across
432 pItem->UpdateInfo(item);
433 // TODO: we may wish to use a playable_url parameter here rather than
434 // switching the path of the item (eg movie as a folder)
435 pItem->m_strPath = item.m_strPath;
436 pItem->m_bIsFolder = item.m_bIsFolder;
441 pItem->CleanString();
447 for (int i = 0; i < items.Size(); i++)
449 CFileItemPtr pItem = items[i];
450 int playCount = m_database.GetPlayCount(*pItem);
452 pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, playCount > 0);
454 pItem->CleanString();
459 void CGUIWindowVideoNav::UpdateButtons()
461 CGUIWindowVideoBase::UpdateButtons();
463 // Update object count
464 int iItems = m_vecItems->Size();
467 // check for parent dir and "all" items
468 // should always be the first two items
469 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
471 CFileItemPtr pItem = m_vecItems->Get(i);
472 if (pItem->IsParentFolder()) iItems--;
473 if (pItem->m_strPath.Left(4).Equals("/-1/")) iItems--;
476 if (m_vecItems->Size() > 2 &&
477 m_vecItems->Get(m_vecItems->Size()-1)->m_strPath.Left(4).Equals("/-1/"))
481 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
482 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
484 // set the filter label
488 if (m_vecItems->m_strPath.Equals("special://videoplaylists/"))
489 strLabel = g_localizeStrings.Get(136);
491 else if (m_vecItems->IsPlayList())
493 // get playlist name from path
495 URIUtils::Split(m_vecItems->m_strPath, strDummy, strLabel);
497 else if (m_vecItems->m_strPath.Equals("sources://video/"))
498 strLabel = g_localizeStrings.Get(744);
499 // everything else is from a videodb:// path
500 else if (m_vecItems->IsVideoDb())
502 CVideoDatabaseDirectory dir;
503 dir.GetLabel(m_vecItems->m_strPath, strLabel);
506 strLabel = URIUtils::GetFileName(m_vecItems->m_strPath);
508 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
510 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
511 SET_CONTROL_LABEL(CONTROL_BTNSHOWMODE, g_localizeStrings.Get(16100 + watchMode));
513 SET_CONTROL_SELECTED(GetID(), CONTROL_BTNSHOWALL, watchMode != VIDEO_SHOW_ALL);
515 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
517 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNFLATTEN, g_settings.m_bMyVideoNavFlatten);
520 /// \brief Search for names, genres, artists, directors, and plots with search string \e strSearch in the
521 /// \brief video databases and return the found \e items
522 /// \param strSearch The search string
523 /// \param items Items Found
524 void CGUIWindowVideoNav::DoSearch(const CStdString& strSearch, CFileItemList& items)
526 CFileItemList tempItems;
527 CStdString strGenre = g_localizeStrings.Get(515); // Genre
528 CStdString strActor = g_localizeStrings.Get(20337); // Actor
529 CStdString strDirector = g_localizeStrings.Get(20339); // Director
530 CStdString strMovie = g_localizeStrings.Get(20338); // Movie
533 m_database.GetMoviesByName(strSearch, tempItems);
534 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20338) + "] ", items);
536 m_database.GetEpisodesByName(strSearch, tempItems);
537 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20359) + "] ", items);
539 m_database.GetTvShowsByName(strSearch, tempItems);
540 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20364) + "] ", items);
542 m_database.GetMusicVideosByName(strSearch, tempItems);
543 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20391) + "] ", items);
545 m_database.GetMusicVideosByAlbum(strSearch, tempItems);
546 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(558) + "] ", items);
548 // get matching genres
549 m_database.GetMovieGenresByName(strSearch, tempItems);
550 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20342) + "] ", items);
552 m_database.GetTvShowGenresByName(strSearch, tempItems);
553 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20343) + "] ", items);
555 m_database.GetMusicVideoGenresByName(strSearch, tempItems);
556 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20389) + "] ", items);
559 m_database.GetMovieActorsByName(strSearch, tempItems);
560 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20342) + "] ", items);
562 m_database.GetTvShowsActorsByName(strSearch, tempItems);
563 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20343) + "] ", items);
565 m_database.GetMusicVideoArtistsByName(strSearch, tempItems);
566 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20389) + "] ", items);
569 m_database.GetMovieDirectorsByName(strSearch, tempItems);
570 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20342) + "] ", items);
572 m_database.GetTvShowsDirectorsByName(strSearch, tempItems);
573 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20343) + "] ", items);
575 m_database.GetMusicVideoDirectorsByName(strSearch, tempItems);
576 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20389) + "] ", items);
579 m_database.GetEpisodesByPlot(strSearch, tempItems);
580 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20365) + "] ", items);
582 m_database.GetMoviesByPlot(strSearch, tempItems);
583 AppendAndClearSearchItems(tempItems, "[" + strMovie + " " + g_localizeStrings.Get(207) + "] ", items);
586 void CGUIWindowVideoNav::PlayItem(int iItem)
588 // unlike additemtoplaylist, we need to check the items here
589 // before calling it since the current playlist will be stopped
592 // root is not allowed
593 if (m_vecItems->IsVirtualDirectoryRoot())
596 CGUIWindowVideoBase::PlayItem(iItem);
599 void CGUIWindowVideoNav::OnInfo(CFileItem* pItem, ADDON::ScraperPtr& scraper)
601 m_database.Open(); // since we can be called from the music library without being inited
602 if (pItem->IsVideoDb())
603 scraper = m_database.GetScraperForPath(pItem->GetVideoInfoTag()->m_strPath);
606 CStdString strPath,strFile;
607 URIUtils::Split(pItem->m_strPath,strPath,strFile);
608 scraper = m_database.GetScraperForPath(strPath);
611 CGUIWindowVideoBase::OnInfo(pItem,scraper);
614 bool CGUIWindowVideoNav::CanDelete(const CStdString& strPath)
617 CVideoDatabaseDirectory::GetQueryParams(strPath,params);
619 if (params.GetMovieId() != -1 ||
620 params.GetEpisodeId() != -1 ||
621 params.GetMVideoId() != -1 ||
622 (params.GetTvShowId() != -1 && params.GetSeason() == -1
623 && !CVideoDatabaseDirectory::IsAllItem(strPath)))
629 void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
631 if (m_vecItems->IsParentFolder())
634 if (!m_vecItems->IsVideoDb())
636 if (!pItem->m_strPath.Equals("newsmartplaylist://video") &&
637 !pItem->m_strPath.Equals("special://videoplaylists/") &&
638 !pItem->m_strPath.Equals("sources://video/"))
639 CGUIWindowVideoBase::OnDeleteItem(pItem);
641 else if (pItem->m_strPath.Left(14).Equals("videodb://1/7/") &&
642 pItem->m_strPath.size() > 14 && pItem->m_bIsFolder)
644 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
645 pDialog->SetLine(0, g_localizeStrings.Get(432));
647 strLabel.Format(g_localizeStrings.Get(433),pItem->GetLabel());
648 pDialog->SetLine(1, strLabel);
649 pDialog->SetLine(2, "");;
651 if (pDialog->IsConfirmed())
654 CDirectory::GetDirectory(pItem->m_strPath,items,"",false,false,DIR_CACHE_ONCE,true,true);
655 for (int i=0;i<items.Size();++i)
656 OnDeleteItem(items[i]);
658 CVideoDatabaseDirectory dir;
660 dir.GetQueryParams(pItem->m_strPath,params);
661 m_database.DeleteSet(params.GetSetId());
666 if (!DeleteItem(pItem.get()))
669 CStdString strDeletePath;
670 if (pItem->m_bIsFolder)
671 strDeletePath=pItem->GetVideoInfoTag()->m_strPath;
673 strDeletePath=pItem->GetVideoInfoTag()->m_strFileNameAndPath;
675 if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
677 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
678 if (strDeletePath.Right(9).Equals("VIDEO_TS/"))
680 URIUtils::RemoveSlashAtEnd(strDeletePath);
681 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
684 if (URIUtils::HasSlashAtEnd(strDeletePath))
685 pItem->m_bIsFolder=true;
687 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
688 CUtil::SupportsFileOperations(strDeletePath))
690 pItem->m_strPath = strDeletePath;
691 CGUIWindowVideoBase::OnDeleteItem(pItem);
695 CUtil::DeleteVideoDatabaseDirectoryCache();
698 bool CGUIWindowVideoNav::DeleteItem(CFileItem* pItem, bool bUnavailable /* = false */)
700 if (!pItem->HasVideoInfoTag() || !CanDelete(pItem->m_strPath))
703 VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES;
704 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty())
705 iType = VIDEODB_CONTENT_TVSHOWS;
706 if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iSeason > -1 && !pItem->m_bIsFolder)
707 iType = VIDEODB_CONTENT_EPISODES;
708 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strArtist.IsEmpty())
709 iType = VIDEODB_CONTENT_MUSICVIDEOS;
711 // dont allow update while scanning
712 CGUIDialogVideoScan* pDialogScan = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
713 if (pDialogScan && pDialogScan->IsScanning())
715 CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
720 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
723 if (iType == VIDEODB_CONTENT_MOVIES)
724 pDialog->SetHeading(432);
725 if (iType == VIDEODB_CONTENT_EPISODES)
726 pDialog->SetHeading(20362);
727 if (iType == VIDEODB_CONTENT_TVSHOWS)
728 pDialog->SetHeading(20363);
729 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
730 pDialog->SetHeading(20392);
734 pDialog->SetLine(0, g_localizeStrings.Get(662));
735 pDialog->SetLine(1, g_localizeStrings.Get(663));
736 pDialog->SetLine(2, "");;
742 strLine.Format(g_localizeStrings.Get(433),pItem->GetLabel());
743 pDialog->SetLine(0, strLine);
744 pDialog->SetLine(1, "");
745 pDialog->SetLine(2, "");;
749 if (!pDialog->IsConfirmed())
753 CVideoDatabase database;
756 database.GetFilePathById(pItem->GetVideoInfoTag()->m_iDbId, path, iType);
759 if (iType == VIDEODB_CONTENT_MOVIES)
760 database.DeleteMovie(path);
761 if (iType == VIDEODB_CONTENT_EPISODES)
762 database.DeleteEpisode(path, pItem->GetVideoInfoTag()->m_iDbId);
763 if (iType == VIDEODB_CONTENT_TVSHOWS)
764 database.DeleteTvShow(path);
765 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
766 database.DeleteMusicVideo(path);
768 if (iType == VIDEODB_CONTENT_TVSHOWS)
769 database.SetPathHash(path,"");
772 CStdString strDirectory;
773 URIUtils::GetDirectory(path,strDirectory);
774 database.SetPathHash(strDirectory,"");
780 void CGUIWindowVideoNav::OnPrepareFileItems(CFileItemList &items)
782 CGUIWindowVideoBase::OnPrepareFileItems(items);
786 CVideoDatabaseDirectory dir;
787 dir.GetQueryParams(items.m_strPath,params);
788 if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
789 CGUIWindowMusicNav::SetupFanart(items);
791 NODE_TYPE node = dir.GetDirectoryChildType(items.m_strPath);
793 // now filter as necessary
794 bool filterWatched=false;
795 if (node == NODE_TYPE_EPISODES
796 || node == NODE_TYPE_SEASONS
797 || node == NODE_TYPE_TITLE_MOVIES
798 || node == NODE_TYPE_TITLE_TVSHOWS
799 || node == NODE_TYPE_TITLE_MUSICVIDEOS
800 || node == NODE_TYPE_RECENTLY_ADDED_EPISODES
801 || node == NODE_TYPE_RECENTLY_ADDED_MOVIES
802 || node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
803 filterWatched = true;
804 if (!items.IsVideoDb())
805 filterWatched = true;
806 if (items.IsSmartPlayList() && items.GetContent() == "tvshows")
807 node = NODE_TYPE_TITLE_TVSHOWS; // so that the check below works
809 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
811 for (int i = 0; i < items.Size(); i++)
813 CFileItemPtr item = items.Get(i);
814 if(item->HasVideoInfoTag() && (node == NODE_TYPE_TITLE_TVSHOWS || node == NODE_TYPE_SEASONS))
816 if (watchMode == VIDEO_SHOW_UNWATCHED)
817 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("unwatchedepisodes");
818 if (watchMode == VIDEO_SHOW_WATCHED)
819 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("watchedepisodes");
820 item->SetProperty("numepisodes", item->GetVideoInfoTag()->m_iEpisode);
825 if((watchMode==VIDEO_SHOW_WATCHED && item->GetVideoInfoTag()->m_playCount== 0)
826 || (watchMode==VIDEO_SHOW_UNWATCHED && item->GetVideoInfoTag()->m_playCount > 0))
835 void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
838 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
839 item = m_vecItems->Get(itemNumber);
841 CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons);
843 if (item && item->GetPropertyBOOL("pluginreplacecontextitems"))
846 CVideoDatabaseDirectory dir;
847 NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->m_strPath);
851 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
852 if (pScanDlg && pScanDlg->IsScanning())
853 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
855 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
857 else if (m_vecItems->m_strPath.Equals("sources://video/"))
859 // get the usual shares
860 CGUIDialogContextMenu::GetContextButtons("video", item, buttons);
861 // add scan button somewhere here
862 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
863 if (pScanDlg && pScanDlg->IsScanning())
864 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning
865 if (!item->IsDVD() && item->m_strPath != "add" &&
866 (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
868 CVideoDatabase database;
870 ADDON::ScraperPtr info = database.GetScraperForPath(item->m_strPath);
872 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
874 if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
876 if (info && info->Content() != CONTENT_NONE)
877 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
879 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
883 if (info && (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning())))
884 buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
889 ADDON::ScraperPtr info;
890 VIDEO::SScanSettings settings;
891 GetScraperForItem(item.get(), info, settings);
893 if (info && info->Content() == CONTENT_TVSHOWS)
894 buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352);
895 else if (info && info->Content() == CONTENT_MUSICVIDEOS)
896 buttons.Add(CONTEXT_BUTTON_INFO,20393);
897 else if (!item->m_bIsFolder && !item->m_strPath.Left(19).Equals("newsmartplaylist://"))
898 buttons.Add(CONTEXT_BUTTON_INFO, 13346);
900 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strArtist.IsEmpty())
902 CMusicDatabase database;
904 if (database.GetArtistByName(item->GetVideoInfoTag()->m_strArtist) > -1)
905 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396);
907 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0)
909 CMusicDatabase database;
911 if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1)
912 buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397);
914 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 &&
915 item->GetVideoInfoTag()->m_strArtist.size() > 0 &&
916 item->GetVideoInfoTag()->m_strTitle.size() > 0)
918 CMusicDatabase database;
920 if (database.GetSongByArtistAndAlbumAndTitle(item->GetVideoInfoTag()->m_strArtist,
921 item->GetVideoInfoTag()->m_strAlbum,
922 item->GetVideoInfoTag()->m_strTitle) > -1)
924 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398);
927 if (!item->IsParentFolder())
929 // can we update the database?
930 if (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
932 if (node == NODE_TYPE_TITLE_TVSHOWS)
934 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
935 if (pScanDlg && pScanDlg->IsScanning())
936 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
938 buttons.Add(CONTEXT_BUTTON_UPDATE_TVSHOW, 13349);
940 if (!item->IsPlugin() && !item->IsLiveTV() && !item->IsAddonsPath() &&
941 item->m_strPath != "sources://video/" && item->m_strPath != "special://videoplaylists/")
943 if (item->m_bIsFolder)
945 // Have both options for folders since we don't know whether all childs are watched/unwatched
946 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
947 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
951 if (item->GetOverlayImage().Equals("OverlayWatched.png"))
952 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
954 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
957 if ((node == NODE_TYPE_TITLE_TVSHOWS) ||
958 (item->IsVideoDb() && item->HasVideoInfoTag() && !item->m_bIsFolder))
960 buttons.Add(CONTEXT_BUTTON_EDIT, 16105); //Edit Title
962 if (m_database.HasContent(VIDEODB_CONTENT_TVSHOWS) && item->HasVideoInfoTag() &&
963 !item->m_bIsFolder && item->GetVideoInfoTag()->m_iEpisode == -1 &&
964 item->GetVideoInfoTag()->m_strArtist.IsEmpty() && item->GetVideoInfoTag()->m_iDbId >= 0) // movie entry
966 if (m_database.IsLinkedToTvshow(item->GetVideoInfoTag()->m_iDbId))
967 buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE,20385);
968 buttons.Add(CONTEXT_BUTTON_LINK_MOVIE,20384);
971 if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
972 buttons.Add(CONTEXT_BUTTON_SET_SEASON_THUMB, 20371);
974 if (item->m_strPath.Left(14).Equals("videodb://1/7/") && item->m_strPath.size() > 14 && item->m_bIsFolder) // sets
976 buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
977 buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_THUMB, 20435);
978 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
981 if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder)
983 if (m_vecItems->m_strPath.Left(11).Equals("videodb://3")) // mvids
984 buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
986 buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
988 if (item->IsVideoDb() && item->HasVideoInfoTag() &&
989 (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS))
991 if (info && info->Content() == CONTENT_TVSHOWS)
993 if(item->GetVideoInfoTag()->m_iBookmarkId != -1 &&
994 item->GetVideoInfoTag()->m_iBookmarkId != 0)
996 buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
999 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
1002 // this should ideally be non-contextual (though we need some context for non-tv show node I guess)
1003 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1004 if (pScanDlg && pScanDlg->IsScanning())
1006 if (node != NODE_TYPE_TITLE_TVSHOWS)
1007 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
1010 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
1013 if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
1014 { // non-video db items, file operations are allowed
1015 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
1016 CUtil::SupportsFileOperations(item->m_strPath))
1018 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
1019 buttons.Add(CONTEXT_BUTTON_RENAME, 118);
1021 // add "Set/Change content" to folders
1022 if (item->m_bIsFolder && !item->IsPlayList() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
1024 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1025 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
1027 if (info && info->Content() != CONTENT_NONE)
1028 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
1030 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
1034 if (item->IsPlugin() || item->m_strPath.Left(9).Equals("script://") || m_vecItems->IsPlugin())
1035 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
1038 CGUIWindowVideoBase::GetNonContextButtons(itemNumber, buttons);
1041 bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
1044 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
1045 item = m_vecItems->Get(itemNumber);
1046 if (CGUIDialogContextMenu::OnContextButton("video", item, button))
1048 //TODO should we search DB for entries from plugins?
1049 if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin()
1050 && !item->IsLiveTV() &&!item->IsRSS())
1052 OnUnAssignContent(item->m_strPath,20375,20340,20341);
1054 Update(m_vecItems->m_strPath);
1059 case CONTEXT_BUTTON_EDIT:
1060 UpdateVideoTitle(item.get());
1061 CUtil::DeleteVideoDatabaseDirectoryCache();
1062 Update(m_vecItems->m_strPath);
1065 case CONTEXT_BUTTON_SET_SEASON_THUMB:
1066 case CONTEXT_BUTTON_SET_ACTOR_THUMB:
1067 case CONTEXT_BUTTON_SET_ARTIST_THUMB:
1068 case CONTEXT_BUTTON_SET_MOVIESET_THUMB:
1070 // Grab the thumbnails from the web
1072 CFileItemList items;
1073 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,"imdbthumbs",strPath);
1074 CFileItemPtr cacheItem(new CFileItem(strPath,true));
1075 CFileUtils::DeleteItem(cacheItem,true);
1076 XFILE::CDirectory::Create(strPath);
1077 CFileItemPtr noneitem(new CFileItem("thumb://None", false));
1078 CStdString cachedThumb = m_vecItems->Get(itemNumber)->GetCachedSeasonThumb();
1079 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1080 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedActorThumb();
1081 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1082 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedArtistThumb();
1083 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1084 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedVideoThumb();
1085 if (CFile::Exists(cachedThumb))
1087 CFileItemPtr item(new CFileItem("thumb://Current", false));
1088 item->SetThumbnailImage(cachedThumb);
1089 item->SetLabel(g_localizeStrings.Get(20016));
1092 noneitem->SetIconImage("DefaultFolder.png");
1093 noneitem->SetLabel(g_localizeStrings.Get(20018));
1095 vector<CStdString> thumbs;
1096 if (button != CONTEXT_BUTTON_SET_ARTIST_THUMB)
1099 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1100 m_database.GetTvShowInfo("",tag,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId);
1102 tag = *m_vecItems->Get(itemNumber)->GetVideoInfoTag();
1103 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1104 tag.m_strPictureURL.GetThumbURLs(thumbs, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iSeason);
1106 tag.m_strPictureURL.GetThumbURLs(thumbs);
1108 for (unsigned int i = 0; i < thumbs.size(); i++)
1110 CStdString strItemPath;
1111 strItemPath.Format("thumb://Remote%i",i);
1112 CFileItemPtr item(new CFileItem(strItemPath, false));
1113 item->SetThumbnailImage(thumbs[i]);
1114 item->SetIconImage("DefaultPicture.png");
1115 item->SetLabel(g_localizeStrings.Get(20015));
1118 // TODO: Do we need to clear the cached image?
1119 // CTextureCache::Get().ClearCachedImage(thumbs[i]);
1124 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1126 CStdString picturePath;
1128 CStdString strPath = m_vecItems->Get(itemNumber)->m_strPath;
1129 URIUtils::RemoveSlashAtEnd(strPath);
1131 int nPos=strPath.ReverseFind("/");
1134 // try to guess where the user should start
1135 // browsing for the artist thumb
1136 CMusicDatabase database;
1138 long idArtist=database.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
1139 database.GetArtistPath(idArtist, picturePath);
1142 CStdString strThumb;
1143 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1144 if (XFILE::CFile::Exists(strThumb))
1146 CFileItemPtr pItem(new CFileItem(strThumb,false));
1147 pItem->SetLabel(g_localizeStrings.Get(20017));
1148 pItem->SetThumbnailImage(strThumb);
1153 noneitem->SetIconImage("DefaultArtist.png");
1156 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1158 CStdString picturePath;
1159 CStdString strThumb;
1160 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1161 if (XFILE::CFile::Exists(strThumb))
1163 CFileItemPtr pItem(new CFileItem(strThumb,false));
1164 pItem->SetLabel(g_localizeStrings.Get(20017));
1165 pItem->SetThumbnailImage(strThumb);
1170 noneitem->SetIconImage("DefaultActor.png");
1173 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1174 noneitem->SetIconImage("DefaultVideo.png");
1177 items.Add(noneitem);
1179 VECSOURCES sources=g_settings.m_videoSources;
1180 g_mediaManager.GetLocalDrives(sources);
1182 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources,
1183 g_localizeStrings.Get(20019), result))
1185 return false; // user cancelled
1188 if (result == "thumb://Current")
1189 return false; // user chose the one they have
1191 // delete the thumbnail if that's what the user wants, else overwrite with the
1193 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1194 if (result.Left(14) == "thumb://Remote")
1196 int number = atoi(result.Mid(14));
1197 CFile::Cache(thumbs[number], cachedThumb);
1199 if (result == "thumb://None")
1200 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1202 CFile::Cache(result,cachedThumb);
1204 CUtil::DeleteVideoDatabaseDirectoryCache();
1205 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
1206 g_windowManager.SendMessage(msg);
1207 Update(m_vecItems->m_strPath);
1211 case CONTEXT_BUTTON_UPDATE_LIBRARY:
1216 case CONTEXT_BUTTON_UNLINK_MOVIE:
1218 OnLinkMovieToTvShow(itemNumber, true);
1219 Update(m_vecItems->m_strPath);
1222 case CONTEXT_BUTTON_LINK_MOVIE:
1224 OnLinkMovieToTvShow(itemNumber, false);
1227 case CONTEXT_BUTTON_GO_TO_ARTIST:
1230 CMusicDatabase database;
1232 strPath.Format("musicdb://2/%ld/",database.GetArtistByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist));
1233 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1236 case CONTEXT_BUTTON_GO_TO_ALBUM:
1239 CMusicDatabase database;
1241 strPath.Format("musicdb://3/%ld/",database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum));
1242 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1245 case CONTEXT_BUTTON_PLAY_OTHER:
1247 CMusicDatabase database;
1250 if (database.GetSongById(database.GetSongByArtistAndAlbumAndTitle(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum,
1251 m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle),
1254 g_application.getApplicationMessenger().PlayFile(song);
1259 case CONTEXT_BUTTON_UNLINK_BOOKMARK:
1262 m_database.DeleteBookMarkForEpisode(*m_vecItems->Get(itemNumber)->GetVideoInfoTag());
1264 CUtil::DeleteVideoDatabaseDirectoryCache();
1265 Update(m_vecItems->m_strPath);
1273 return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
1276 void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove)
1282 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1284 for (unsigned int i=0;i<ids.size();++i)
1287 m_database.GetTvShowInfo("",tag,ids[i]);
1288 CFileItemPtr show(new CFileItem(tag));
1294 m_database.GetTvShowsNav("videodb://2/2",list);
1296 // remove already linked shows
1298 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1300 for (int i=0;i<list.Size();)
1303 for (j=0;j<ids.size();++j)
1305 if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j])
1308 if (j == ids.size())
1314 int iSelectedLabel = 0;
1315 if (list.Size() > 1)
1317 list.Sort(g_guiSettings.GetBool("filelists.ignorethewhensorting") ? SORT_METHOD_LABEL_IGNORE_THE : SORT_METHOD_LABEL, SORT_ORDER_ASC);
1318 CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
1320 pDialog->SetItems(&list);
1321 pDialog->SetHeading(20356);
1323 iSelectedLabel = pDialog->GetSelectedLabel();
1325 if (iSelectedLabel > -1)
1327 m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,
1328 list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove);
1329 CUtil::DeleteVideoDatabaseDirectoryCache();
1333 bool CGUIWindowVideoNav::OnClick(int iItem)
1335 CFileItemPtr item = m_vecItems->Get(iItem);
1336 if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
1338 if (!DeleteItem(item.get(), true))
1342 m_vecItems->RemoveDiscCache(GetID());
1343 Update(m_vecItems->m_strPath);
1344 m_viewControl.SetSelectedItem(iItem);
1348 return CGUIWindowVideoBase::OnClick(iItem);
1351 CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
1353 if (dir.Equals("MovieGenres"))
1354 return "videodb://1/1/";
1355 else if (dir.Equals("MovieTitles"))
1356 return "videodb://1/2/";
1357 else if (dir.Equals("MovieYears"))
1358 return "videodb://1/3/";
1359 else if (dir.Equals("MovieActors"))
1360 return "videodb://1/4/";
1361 else if (dir.Equals("MovieDirectors"))
1362 return "videodb://1/5/";
1363 else if (dir.Equals("MovieStudios"))
1364 return "videodb://1/6/";
1365 else if (dir.Equals("MovieSets"))
1366 return "videodb://1/7/";
1367 else if (dir.Equals("MovieCountries"))
1368 return "videodb://1/8/";
1369 else if (dir.Equals("Movies"))
1370 return "videodb://1/";
1371 else if (dir.Equals("TvShowGenres"))
1372 return "videodb://2/1/";
1373 else if (dir.Equals("TvShowTitles"))
1374 return "videodb://2/2/";
1375 else if (dir.Equals("TvShowYears"))
1376 return "videodb://2/3/";
1377 else if (dir.Equals("TvShowActors"))
1378 return "videodb://2/4/";
1379 else if (dir.Equals("TvShowStudios"))
1380 return "videodb://2/5/";
1381 else if (dir.Equals("TvShows"))
1382 return "videodb://2/";
1383 else if (dir.Equals("MusicVideoGenres"))
1384 return "videodb://3/1/";
1385 else if (dir.Equals("MusicVideoTitles"))
1386 return "videodb://3/2/";
1387 else if (dir.Equals("MusicVideoYears"))
1388 return "videodb://3/3/";
1389 else if (dir.Equals("MusicVideoArtists"))
1390 return "videodb://3/4/";
1391 else if (dir.Equals("MusicVideoDirectors"))
1392 return "videodb://3/5/";
1393 else if (dir.Equals("MusicVideoStudios"))
1394 return "videodb://3/6/";
1395 else if (dir.Equals("MusicVideos"))
1396 return "videodb://3/";
1397 else if (dir.Equals("RecentlyAddedMovies"))
1398 return "videodb://4/";
1399 else if (dir.Equals("RecentlyAddedEpisodes"))
1400 return "videodb://5/";
1401 else if (dir.Equals("RecentlyAddedMusicVideos"))
1402 return "videodb://6/";
1403 else if (dir.Equals("Files"))
1404 return "sources://video/";
1405 return CGUIWindowVideoBase::GetStartFolder(dir);