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);
412 bool clean = (g_guiSettings.GetBool("myvideos.cleanstrings") &&
413 !items.IsVirtualDirectoryRoot() &&
414 m_stackingAvailable);
416 if (!content.IsEmpty())
418 for (int i = 0; i < items.Size(); i++)
420 CFileItemPtr pItem = items[i];
422 if (m_database.GetItemForPath(content, pItem->m_strPath, item))
423 { // copy info across
424 pItem->UpdateInfo(item);
425 // TODO: we may wish to use a playable_url parameter here rather than
426 // switching the path of the item (eg movie as a folder)
427 pItem->m_strPath = item.m_strPath;
428 pItem->m_bIsFolder = item.m_bIsFolder;
433 pItem->CleanString();
439 for (int i = 0; i < items.Size(); i++)
441 CFileItemPtr pItem = items[i];
442 int playCount = m_database.GetPlayCount(*pItem);
444 pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, playCount > 0);
446 pItem->CleanString();
451 void CGUIWindowVideoNav::UpdateButtons()
453 CGUIWindowVideoBase::UpdateButtons();
455 // Update object count
456 int iItems = m_vecItems->Size();
459 // check for parent dir and "all" items
460 // should always be the first two items
461 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
463 CFileItemPtr pItem = m_vecItems->Get(i);
464 if (pItem->IsParentFolder()) iItems--;
465 if (pItem->m_strPath.Left(4).Equals("/-1/")) iItems--;
468 if (m_vecItems->Size() > 2 &&
469 m_vecItems->Get(m_vecItems->Size()-1)->m_strPath.Left(4).Equals("/-1/"))
473 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
474 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
476 // set the filter label
480 if (m_vecItems->m_strPath.Equals("special://videoplaylists/"))
481 strLabel = g_localizeStrings.Get(136);
483 else if (m_vecItems->IsPlayList())
485 // get playlist name from path
487 URIUtils::Split(m_vecItems->m_strPath, strDummy, strLabel);
489 else if (m_vecItems->m_strPath.Equals("sources://video/"))
490 strLabel = g_localizeStrings.Get(744);
491 // everything else is from a videodb:// path
492 else if (m_vecItems->IsVideoDb())
494 CVideoDatabaseDirectory dir;
495 dir.GetLabel(m_vecItems->m_strPath, strLabel);
498 strLabel = URIUtils::GetFileName(m_vecItems->m_strPath);
500 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
502 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
503 SET_CONTROL_LABEL(CONTROL_BTNSHOWMODE, g_localizeStrings.Get(16100 + watchMode));
505 SET_CONTROL_SELECTED(GetID(), CONTROL_BTNSHOWALL, watchMode != VIDEO_SHOW_ALL);
507 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
509 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNFLATTEN, g_settings.m_bMyVideoNavFlatten);
512 /// \brief Search for names, genres, artists, directors, and plots with search string \e strSearch in the
513 /// \brief video databases and return the found \e items
514 /// \param strSearch The search string
515 /// \param items Items Found
516 void CGUIWindowVideoNav::DoSearch(const CStdString& strSearch, CFileItemList& items)
518 CFileItemList tempItems;
519 CStdString strGenre = g_localizeStrings.Get(515); // Genre
520 CStdString strActor = g_localizeStrings.Get(20337); // Actor
521 CStdString strDirector = g_localizeStrings.Get(20339); // Director
522 CStdString strMovie = g_localizeStrings.Get(20338); // Movie
525 m_database.GetMoviesByName(strSearch, tempItems);
526 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20338) + "] ", items);
528 m_database.GetEpisodesByName(strSearch, tempItems);
529 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20359) + "] ", items);
531 m_database.GetTvShowsByName(strSearch, tempItems);
532 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20364) + "] ", items);
534 m_database.GetMusicVideosByName(strSearch, tempItems);
535 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20391) + "] ", items);
537 m_database.GetMusicVideosByAlbum(strSearch, tempItems);
538 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(558) + "] ", items);
540 // get matching genres
541 m_database.GetMovieGenresByName(strSearch, tempItems);
542 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20342) + "] ", items);
544 m_database.GetTvShowGenresByName(strSearch, tempItems);
545 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20343) + "] ", items);
547 m_database.GetMusicVideoGenresByName(strSearch, tempItems);
548 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20389) + "] ", items);
551 m_database.GetMovieActorsByName(strSearch, tempItems);
552 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20342) + "] ", items);
554 m_database.GetTvShowsActorsByName(strSearch, tempItems);
555 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20343) + "] ", items);
557 m_database.GetMusicVideoArtistsByName(strSearch, tempItems);
558 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20389) + "] ", items);
561 m_database.GetMovieDirectorsByName(strSearch, tempItems);
562 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20342) + "] ", items);
564 m_database.GetTvShowsDirectorsByName(strSearch, tempItems);
565 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20343) + "] ", items);
567 m_database.GetMusicVideoDirectorsByName(strSearch, tempItems);
568 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20389) + "] ", items);
571 m_database.GetEpisodesByPlot(strSearch, tempItems);
572 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20365) + "] ", items);
574 m_database.GetMoviesByPlot(strSearch, tempItems);
575 AppendAndClearSearchItems(tempItems, "[" + strMovie + " " + g_localizeStrings.Get(207) + "] ", items);
578 void CGUIWindowVideoNav::PlayItem(int iItem)
580 // unlike additemtoplaylist, we need to check the items here
581 // before calling it since the current playlist will be stopped
584 // root is not allowed
585 if (m_vecItems->IsVirtualDirectoryRoot())
588 CGUIWindowVideoBase::PlayItem(iItem);
591 void CGUIWindowVideoNav::OnInfo(CFileItem* pItem, ADDON::ScraperPtr& scraper)
593 m_database.Open(); // since we can be called from the music library without being inited
594 if (pItem->IsVideoDb())
595 scraper = m_database.GetScraperForPath(pItem->GetVideoInfoTag()->m_strPath);
598 CStdString strPath,strFile;
599 URIUtils::Split(pItem->m_strPath,strPath,strFile);
600 scraper = m_database.GetScraperForPath(strPath);
603 CGUIWindowVideoBase::OnInfo(pItem,scraper);
606 bool CGUIWindowVideoNav::CanDelete(const CStdString& strPath)
609 CVideoDatabaseDirectory::GetQueryParams(strPath,params);
611 if (params.GetMovieId() != -1 ||
612 params.GetEpisodeId() != -1 ||
613 params.GetMVideoId() != -1 ||
614 (params.GetTvShowId() != -1 && params.GetSeason() == -1
615 && !CVideoDatabaseDirectory::IsAllItem(strPath)))
621 void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
623 if (m_vecItems->IsParentFolder())
626 if (!m_vecItems->IsVideoDb())
628 if (!pItem->m_strPath.Equals("newsmartplaylist://video") &&
629 !pItem->m_strPath.Equals("special://videoplaylists/") &&
630 !pItem->m_strPath.Equals("sources://video/"))
631 CGUIWindowVideoBase::OnDeleteItem(pItem);
633 else if (pItem->m_strPath.Left(14).Equals("videodb://1/7/") &&
634 pItem->m_strPath.size() > 14 && pItem->m_bIsFolder)
636 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
637 pDialog->SetLine(0, g_localizeStrings.Get(432));
639 strLabel.Format(g_localizeStrings.Get(433),pItem->GetLabel());
640 pDialog->SetLine(1, strLabel);
641 pDialog->SetLine(2, "");;
643 if (pDialog->IsConfirmed())
646 CDirectory::GetDirectory(pItem->m_strPath,items,"",false,false,DIR_CACHE_ONCE,true,true);
647 for (int i=0;i<items.Size();++i)
648 OnDeleteItem(items[i]);
650 CVideoDatabaseDirectory dir;
652 dir.GetQueryParams(pItem->m_strPath,params);
653 m_database.DeleteSet(params.GetSetId());
658 if (!DeleteItem(pItem.get()))
661 CStdString strDeletePath;
662 if (pItem->m_bIsFolder)
663 strDeletePath=pItem->GetVideoInfoTag()->m_strPath;
665 strDeletePath=pItem->GetVideoInfoTag()->m_strFileNameAndPath;
667 if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
669 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
670 if (strDeletePath.Right(9).Equals("VIDEO_TS/"))
672 URIUtils::RemoveSlashAtEnd(strDeletePath);
673 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
676 if (URIUtils::HasSlashAtEnd(strDeletePath))
677 pItem->m_bIsFolder=true;
679 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
680 CUtil::SupportsFileOperations(strDeletePath))
682 pItem->m_strPath = strDeletePath;
683 CGUIWindowVideoBase::OnDeleteItem(pItem);
687 CUtil::DeleteVideoDatabaseDirectoryCache();
690 bool CGUIWindowVideoNav::DeleteItem(CFileItem* pItem, bool bUnavailable /* = false */)
692 if (!pItem->HasVideoInfoTag() || !CanDelete(pItem->m_strPath))
695 VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES;
696 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty())
697 iType = VIDEODB_CONTENT_TVSHOWS;
698 if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iSeason > -1 && !pItem->m_bIsFolder)
699 iType = VIDEODB_CONTENT_EPISODES;
700 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strArtist.IsEmpty())
701 iType = VIDEODB_CONTENT_MUSICVIDEOS;
703 // dont allow update while scanning
704 CGUIDialogVideoScan* pDialogScan = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
705 if (pDialogScan && pDialogScan->IsScanning())
707 CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
712 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
715 if (iType == VIDEODB_CONTENT_MOVIES)
716 pDialog->SetHeading(432);
717 if (iType == VIDEODB_CONTENT_EPISODES)
718 pDialog->SetHeading(20362);
719 if (iType == VIDEODB_CONTENT_TVSHOWS)
720 pDialog->SetHeading(20363);
721 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
722 pDialog->SetHeading(20392);
726 pDialog->SetLine(0, g_localizeStrings.Get(662));
727 pDialog->SetLine(1, g_localizeStrings.Get(663));
728 pDialog->SetLine(2, "");;
734 strLine.Format(g_localizeStrings.Get(433),pItem->GetLabel());
735 pDialog->SetLine(0, strLine);
736 pDialog->SetLine(1, "");
737 pDialog->SetLine(2, "");;
741 if (!pDialog->IsConfirmed())
745 CVideoDatabase database;
748 database.GetFilePathById(pItem->GetVideoInfoTag()->m_iDbId, path, iType);
751 if (iType == VIDEODB_CONTENT_MOVIES)
752 database.DeleteMovie(path);
753 if (iType == VIDEODB_CONTENT_EPISODES)
754 database.DeleteEpisode(path, pItem->GetVideoInfoTag()->m_iDbId);
755 if (iType == VIDEODB_CONTENT_TVSHOWS)
756 database.DeleteTvShow(path);
757 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
758 database.DeleteMusicVideo(path);
760 if (iType == VIDEODB_CONTENT_TVSHOWS)
761 database.SetPathHash(path,"");
764 CStdString strDirectory;
765 URIUtils::GetDirectory(path,strDirectory);
766 database.SetPathHash(strDirectory,"");
772 void CGUIWindowVideoNav::OnPrepareFileItems(CFileItemList &items)
774 CGUIWindowVideoBase::OnPrepareFileItems(items);
778 CVideoDatabaseDirectory dir;
779 dir.GetQueryParams(items.m_strPath,params);
780 if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
781 CGUIWindowMusicNav::SetupFanart(items);
783 NODE_TYPE node = dir.GetDirectoryChildType(items.m_strPath);
785 // now filter as necessary
786 bool filterWatched=false;
787 if (node == NODE_TYPE_EPISODES
788 || node == NODE_TYPE_SEASONS
789 || node == NODE_TYPE_TITLE_MOVIES
790 || node == NODE_TYPE_TITLE_TVSHOWS
791 || node == NODE_TYPE_TITLE_MUSICVIDEOS
792 || node == NODE_TYPE_RECENTLY_ADDED_EPISODES
793 || node == NODE_TYPE_RECENTLY_ADDED_MOVIES
794 || node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
795 filterWatched = true;
796 if (!items.IsVideoDb())
797 filterWatched = true;
798 if (items.IsSmartPlayList() && items.GetContent() == "tvshows")
799 node = NODE_TYPE_TITLE_TVSHOWS; // so that the check below works
801 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
803 for (int i = 0; i < items.Size(); i++)
805 CFileItemPtr item = items.Get(i);
806 if(item->HasVideoInfoTag() && (node == NODE_TYPE_TITLE_TVSHOWS || node == NODE_TYPE_SEASONS))
808 if (watchMode == VIDEO_SHOW_UNWATCHED)
809 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("unwatchedepisodes");
810 if (watchMode == VIDEO_SHOW_WATCHED)
811 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("watchedepisodes");
812 item->SetProperty("numepisodes", item->GetVideoInfoTag()->m_iEpisode);
817 if((watchMode==VIDEO_SHOW_WATCHED && item->GetVideoInfoTag()->m_playCount== 0)
818 || (watchMode==VIDEO_SHOW_UNWATCHED && item->GetVideoInfoTag()->m_playCount > 0))
827 void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
830 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
831 item = m_vecItems->Get(itemNumber);
833 CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons);
835 if (item && item->GetPropertyBOOL("pluginreplacecontextitems"))
838 CVideoDatabaseDirectory dir;
839 NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->m_strPath);
843 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
844 if (pScanDlg && pScanDlg->IsScanning())
845 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
847 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
849 else if (m_vecItems->m_strPath.Equals("sources://video/"))
851 // get the usual shares
852 CGUIDialogContextMenu::GetContextButtons("video", item, buttons);
853 // add scan button somewhere here
854 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
855 if (pScanDlg && pScanDlg->IsScanning())
856 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning
857 if (!item->IsDVD() && item->m_strPath != "add" &&
858 (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
860 CVideoDatabase database;
862 ADDON::ScraperPtr info = database.GetScraperForPath(item->m_strPath);
864 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
866 if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
868 if (info && info->Content() != CONTENT_NONE)
869 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
871 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
875 if (info && (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning())))
876 buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
881 ADDON::ScraperPtr info;
882 VIDEO::SScanSettings settings;
883 GetScraperForItem(item.get(), info, settings);
885 if (info && info->Content() == CONTENT_TVSHOWS)
886 buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352);
887 else if (info && info->Content() == CONTENT_MUSICVIDEOS)
888 buttons.Add(CONTEXT_BUTTON_INFO,20393);
889 else if (!item->m_bIsFolder && !item->m_strPath.Left(19).Equals("newsmartplaylist://"))
890 buttons.Add(CONTEXT_BUTTON_INFO, 13346);
892 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strArtist.IsEmpty())
894 CMusicDatabase database;
896 if (database.GetArtistByName(item->GetVideoInfoTag()->m_strArtist) > -1)
897 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396);
899 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0)
901 CMusicDatabase database;
903 if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1)
904 buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397);
906 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 &&
907 item->GetVideoInfoTag()->m_strArtist.size() > 0 &&
908 item->GetVideoInfoTag()->m_strTitle.size() > 0)
910 CMusicDatabase database;
912 if (database.GetSongByArtistAndAlbumAndTitle(item->GetVideoInfoTag()->m_strArtist,
913 item->GetVideoInfoTag()->m_strAlbum,
914 item->GetVideoInfoTag()->m_strTitle) > -1)
916 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398);
919 if (!item->IsParentFolder())
921 // can we update the database?
922 if (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
924 if (node == NODE_TYPE_TITLE_TVSHOWS)
926 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
927 if (pScanDlg && pScanDlg->IsScanning())
928 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
930 buttons.Add(CONTEXT_BUTTON_UPDATE_TVSHOW, 13349);
932 if (!item->IsPlugin() && !item->IsLiveTV() && !item->IsAddonsPath() &&
933 item->m_strPath != "sources://video/" && item->m_strPath != "special://videoplaylists/")
935 if (item->m_bIsFolder)
937 // Have both options for folders since we don't know whether all childs are watched/unwatched
938 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
939 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
943 if (item->GetOverlayImage().Equals("OverlayWatched.png"))
944 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
946 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
949 if ((node == NODE_TYPE_TITLE_TVSHOWS) ||
950 (item->IsVideoDb() && item->HasVideoInfoTag() && !item->m_bIsFolder))
952 buttons.Add(CONTEXT_BUTTON_EDIT, 16105); //Edit Title
954 if (m_database.HasContent(VIDEODB_CONTENT_TVSHOWS) && item->HasVideoInfoTag() &&
955 !item->m_bIsFolder && item->GetVideoInfoTag()->m_iEpisode == -1 &&
956 item->GetVideoInfoTag()->m_strArtist.IsEmpty() && item->GetVideoInfoTag()->m_iDbId >= 0) // movie entry
958 if (m_database.IsLinkedToTvshow(item->GetVideoInfoTag()->m_iDbId))
959 buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE,20385);
960 buttons.Add(CONTEXT_BUTTON_LINK_MOVIE,20384);
963 if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
964 buttons.Add(CONTEXT_BUTTON_SET_SEASON_THUMB, 20371);
966 if (item->m_strPath.Left(14).Equals("videodb://1/7/") && item->m_strPath.size() > 14 && item->m_bIsFolder) // sets
968 buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
969 buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_THUMB, 20435);
970 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
973 if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder)
975 if (m_vecItems->m_strPath.Left(11).Equals("videodb://3")) // mvids
976 buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
978 buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
980 if (item->IsVideoDb() && item->HasVideoInfoTag() &&
981 (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS))
983 if (info && info->Content() == CONTENT_TVSHOWS)
985 if(item->GetVideoInfoTag()->m_iBookmarkId != -1 &&
986 item->GetVideoInfoTag()->m_iBookmarkId != 0)
988 buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
991 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
994 // this should ideally be non-contextual (though we need some context for non-tv show node I guess)
995 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
996 if (pScanDlg && pScanDlg->IsScanning())
998 if (node != NODE_TYPE_TITLE_TVSHOWS)
999 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
1002 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
1005 if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
1006 { // non-video db items, file operations are allowed
1007 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
1008 CUtil::SupportsFileOperations(item->m_strPath))
1010 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
1011 buttons.Add(CONTEXT_BUTTON_RENAME, 118);
1013 // add "Set/Change content" to folders
1014 if (item->m_bIsFolder && !item->IsPlayList() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
1016 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1017 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
1019 if (info && info->Content() != CONTENT_NONE)
1020 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
1022 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
1026 if (item->IsPlugin() || item->m_strPath.Left(9).Equals("script://") || m_vecItems->IsPlugin())
1027 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
1030 CGUIWindowVideoBase::GetNonContextButtons(itemNumber, buttons);
1033 bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
1036 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
1037 item = m_vecItems->Get(itemNumber);
1038 if (CGUIDialogContextMenu::OnContextButton("video", item, button))
1040 //TODO should we search DB for entries from plugins?
1041 if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin()
1042 && !item->IsLiveTV() &&!item->IsRSS())
1044 OnUnAssignContent(item->m_strPath,20375,20340,20341);
1046 Update(m_vecItems->m_strPath);
1051 case CONTEXT_BUTTON_EDIT:
1052 UpdateVideoTitle(item.get());
1053 CUtil::DeleteVideoDatabaseDirectoryCache();
1054 Update(m_vecItems->m_strPath);
1057 case CONTEXT_BUTTON_SET_SEASON_THUMB:
1058 case CONTEXT_BUTTON_SET_ACTOR_THUMB:
1059 case CONTEXT_BUTTON_SET_ARTIST_THUMB:
1060 case CONTEXT_BUTTON_SET_MOVIESET_THUMB:
1062 // Grab the thumbnails from the web
1064 CFileItemList items;
1065 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,"imdbthumbs",strPath);
1066 CFileItemPtr cacheItem(new CFileItem(strPath,true));
1067 CFileUtils::DeleteItem(cacheItem,true);
1068 XFILE::CDirectory::Create(strPath);
1069 CFileItemPtr noneitem(new CFileItem("thumb://None", false));
1070 CStdString cachedThumb = m_vecItems->Get(itemNumber)->GetCachedSeasonThumb();
1071 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1072 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedActorThumb();
1073 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1074 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedArtistThumb();
1075 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1076 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedVideoThumb();
1077 if (CFile::Exists(cachedThumb))
1079 CFileItemPtr item(new CFileItem("thumb://Current", false));
1080 item->SetThumbnailImage(cachedThumb);
1081 item->SetLabel(g_localizeStrings.Get(20016));
1084 noneitem->SetIconImage("DefaultFolder.png");
1085 noneitem->SetLabel(g_localizeStrings.Get(20018));
1087 vector<CStdString> thumbs;
1088 if (button != CONTEXT_BUTTON_SET_ARTIST_THUMB)
1091 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1092 m_database.GetTvShowInfo("",tag,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId);
1094 tag = *m_vecItems->Get(itemNumber)->GetVideoInfoTag();
1095 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1096 tag.m_strPictureURL.GetThumbURLs(thumbs, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iSeason);
1098 tag.m_strPictureURL.GetThumbURLs(thumbs);
1100 for (unsigned int i = 0; i < thumbs.size(); i++)
1102 CStdString strItemPath;
1103 strItemPath.Format("thumb://Remote%i",i);
1104 CFileItemPtr item(new CFileItem(strItemPath, false));
1105 item->SetThumbnailImage(thumbs[i]);
1106 item->SetIconImage("DefaultPicture.png");
1107 item->SetLabel(g_localizeStrings.Get(20015));
1110 // TODO: Do we need to clear the cached image?
1111 // CTextureCache::Get().ClearCachedImage(thumbs[i]);
1116 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1118 CStdString picturePath;
1120 CStdString strPath = m_vecItems->Get(itemNumber)->m_strPath;
1121 URIUtils::RemoveSlashAtEnd(strPath);
1123 int nPos=strPath.ReverseFind("/");
1126 // try to guess where the user should start
1127 // browsing for the artist thumb
1128 CMusicDatabase database;
1130 long idArtist=database.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
1131 database.GetArtistPath(idArtist, picturePath);
1134 CStdString strThumb;
1135 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1136 if (XFILE::CFile::Exists(strThumb))
1138 CFileItemPtr pItem(new CFileItem(strThumb,false));
1139 pItem->SetLabel(g_localizeStrings.Get(20017));
1140 pItem->SetThumbnailImage(strThumb);
1145 noneitem->SetIconImage("DefaultArtist.png");
1148 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1150 CStdString picturePath;
1151 CStdString strThumb;
1152 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1153 if (XFILE::CFile::Exists(strThumb))
1155 CFileItemPtr pItem(new CFileItem(strThumb,false));
1156 pItem->SetLabel(g_localizeStrings.Get(20017));
1157 pItem->SetThumbnailImage(strThumb);
1162 noneitem->SetIconImage("DefaultActor.png");
1165 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1166 noneitem->SetIconImage("DefaultVideo.png");
1169 items.Add(noneitem);
1171 VECSOURCES sources=g_settings.m_videoSources;
1172 g_mediaManager.GetLocalDrives(sources);
1174 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources,
1175 g_localizeStrings.Get(20019), result))
1177 return false; // user cancelled
1180 if (result == "thumb://Current")
1181 return false; // user chose the one they have
1183 // delete the thumbnail if that's what the user wants, else overwrite with the
1185 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1186 if (result.Left(14) == "thumb://Remote")
1188 int number = atoi(result.Mid(14));
1189 CFile::Cache(thumbs[number], cachedThumb);
1191 if (result == "thumb://None")
1192 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1194 CFile::Cache(result,cachedThumb);
1196 CUtil::DeleteVideoDatabaseDirectoryCache();
1197 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
1198 g_windowManager.SendMessage(msg);
1199 Update(m_vecItems->m_strPath);
1203 case CONTEXT_BUTTON_UPDATE_LIBRARY:
1208 case CONTEXT_BUTTON_UNLINK_MOVIE:
1210 OnLinkMovieToTvShow(itemNumber, true);
1211 Update(m_vecItems->m_strPath);
1214 case CONTEXT_BUTTON_LINK_MOVIE:
1216 OnLinkMovieToTvShow(itemNumber, false);
1219 case CONTEXT_BUTTON_GO_TO_ARTIST:
1222 CMusicDatabase database;
1224 strPath.Format("musicdb://2/%ld/",database.GetArtistByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist));
1225 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1228 case CONTEXT_BUTTON_GO_TO_ALBUM:
1231 CMusicDatabase database;
1233 strPath.Format("musicdb://3/%ld/",database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum));
1234 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1237 case CONTEXT_BUTTON_PLAY_OTHER:
1239 CMusicDatabase database;
1242 if (database.GetSongById(database.GetSongByArtistAndAlbumAndTitle(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum,
1243 m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle),
1246 g_application.getApplicationMessenger().PlayFile(song);
1251 case CONTEXT_BUTTON_UNLINK_BOOKMARK:
1254 m_database.DeleteBookMarkForEpisode(*m_vecItems->Get(itemNumber)->GetVideoInfoTag());
1256 CUtil::DeleteVideoDatabaseDirectoryCache();
1257 Update(m_vecItems->m_strPath);
1265 return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
1268 void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove)
1274 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1276 for (unsigned int i=0;i<ids.size();++i)
1279 m_database.GetTvShowInfo("",tag,ids[i]);
1280 CFileItemPtr show(new CFileItem(tag));
1286 m_database.GetTvShowsNav("videodb://2/2",list);
1288 // remove already linked shows
1290 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1292 for (int i=0;i<list.Size();)
1295 for (j=0;j<ids.size();++j)
1297 if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j])
1300 if (j == ids.size())
1306 int iSelectedLabel = 0;
1307 if (list.Size() > 1)
1309 list.Sort(g_guiSettings.GetBool("filelists.ignorethewhensorting") ? SORT_METHOD_LABEL_IGNORE_THE : SORT_METHOD_LABEL, SORT_ORDER_ASC);
1310 CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
1312 pDialog->SetItems(&list);
1313 pDialog->SetHeading(20356);
1315 iSelectedLabel = pDialog->GetSelectedLabel();
1317 if (iSelectedLabel > -1)
1319 m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,
1320 list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove);
1321 CUtil::DeleteVideoDatabaseDirectoryCache();
1325 bool CGUIWindowVideoNav::OnClick(int iItem)
1327 CFileItemPtr item = m_vecItems->Get(iItem);
1328 if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
1330 if (!DeleteItem(item.get(), true))
1334 m_vecItems->RemoveDiscCache(GetID());
1335 Update(m_vecItems->m_strPath);
1336 m_viewControl.SetSelectedItem(iItem);
1340 return CGUIWindowVideoBase::OnClick(iItem);
1343 CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
1345 if (dir.Equals("MovieGenres"))
1346 return "videodb://1/1/";
1347 else if (dir.Equals("MovieTitles"))
1348 return "videodb://1/2/";
1349 else if (dir.Equals("MovieYears"))
1350 return "videodb://1/3/";
1351 else if (dir.Equals("MovieActors"))
1352 return "videodb://1/4/";
1353 else if (dir.Equals("MovieDirectors"))
1354 return "videodb://1/5/";
1355 else if (dir.Equals("MovieStudios"))
1356 return "videodb://1/6/";
1357 else if (dir.Equals("MovieSets"))
1358 return "videodb://1/7/";
1359 else if (dir.Equals("MovieCountries"))
1360 return "videodb://1/8/";
1361 else if (dir.Equals("Movies"))
1362 return "videodb://1/";
1363 else if (dir.Equals("TvShowGenres"))
1364 return "videodb://2/1/";
1365 else if (dir.Equals("TvShowTitles"))
1366 return "videodb://2/2/";
1367 else if (dir.Equals("TvShowYears"))
1368 return "videodb://2/3/";
1369 else if (dir.Equals("TvShowActors"))
1370 return "videodb://2/4/";
1371 else if (dir.Equals("TvShowStudios"))
1372 return "videodb://2/5/";
1373 else if (dir.Equals("TvShows"))
1374 return "videodb://2/";
1375 else if (dir.Equals("MusicVideoGenres"))
1376 return "videodb://3/1/";
1377 else if (dir.Equals("MusicVideoTitles"))
1378 return "videodb://3/2/";
1379 else if (dir.Equals("MusicVideoYears"))
1380 return "videodb://3/3/";
1381 else if (dir.Equals("MusicVideoArtists"))
1382 return "videodb://3/4/";
1383 else if (dir.Equals("MusicVideoDirectors"))
1384 return "videodb://3/5/";
1385 else if (dir.Equals("MusicVideoStudios"))
1386 return "videodb://3/6/";
1387 else if (dir.Equals("MusicVideos"))
1388 return "videodb://3/";
1389 else if (dir.Equals("RecentlyAddedMovies"))
1390 return "videodb://4/";
1391 else if (dir.Equals("RecentlyAddedEpisodes"))
1392 return "videodb://5/";
1393 else if (dir.Equals("RecentlyAddedMusicVideos"))
1394 return "videodb://6/";
1395 else if (dir.Equals("Files"))
1396 return "sources://video/";
1397 return CGUIWindowVideoBase::GetStartFolder(dir);