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
400 if (items.GetLabel().IsEmpty() && m_rootDir.IsSource(items.m_strPath, g_settings.GetSourcesFromType("video"), &label))
401 items.SetLabel(label);
402 LoadVideoInfo(items);
408 void CGUIWindowVideoNav::LoadVideoInfo(CFileItemList &items)
410 // TODO: this could possibly be threaded as per the music info loading,
411 // we could also cache the info
412 if (!items.GetContent().IsEmpty())
413 return; // don't load for listings that have content set
415 CStdString content = m_database.GetContentForPath(items.m_strPath);
416 items.SetContent(content.IsEmpty() ? "files" : content);
418 bool clean = (g_guiSettings.GetBool("myvideos.cleanstrings") &&
419 !items.IsVirtualDirectoryRoot() &&
420 m_stackingAvailable);
422 for (int i = 0; i < items.Size(); i++)
424 CFileItemPtr pItem = items[i];
426 if (!content.IsEmpty() && m_database.GetItemForPath(content, pItem->m_strPath, item))
427 { // copy info across
428 CStdString label (pItem->GetLabel ());
429 CStdString label2(pItem->GetLabel2());
430 pItem->UpdateInfo(item);
431 pItem->SetLabel (label);
432 pItem->SetLabel2(label);
433 if (CFile::Exists(item.GetCachedFanart()))
434 pItem->SetProperty("fanart_image", item.GetCachedFanart());
438 { // grab the playcount and clean the label
439 int playCount = m_database.GetPlayCount(*pItem);
441 pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, playCount > 0);
443 pItem->CleanString();
448 void CGUIWindowVideoNav::UpdateButtons()
450 CGUIWindowVideoBase::UpdateButtons();
452 // Update object count
453 int iItems = m_vecItems->Size();
456 // check for parent dir and "all" items
457 // should always be the first two items
458 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
460 CFileItemPtr pItem = m_vecItems->Get(i);
461 if (pItem->IsParentFolder()) iItems--;
462 if (pItem->m_strPath.Left(4).Equals("/-1/")) iItems--;
465 if (m_vecItems->Size() > 2 &&
466 m_vecItems->Get(m_vecItems->Size()-1)->m_strPath.Left(4).Equals("/-1/"))
470 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
471 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
473 // set the filter label
477 if (m_vecItems->m_strPath.Equals("special://videoplaylists/"))
478 strLabel = g_localizeStrings.Get(136);
480 else if (m_vecItems->IsPlayList())
482 // get playlist name from path
484 URIUtils::Split(m_vecItems->m_strPath, strDummy, strLabel);
486 else if (m_vecItems->m_strPath.Equals("sources://video/"))
487 strLabel = g_localizeStrings.Get(744);
488 // everything else is from a videodb:// path
489 else if (m_vecItems->IsVideoDb())
491 CVideoDatabaseDirectory dir;
492 dir.GetLabel(m_vecItems->m_strPath, strLabel);
495 strLabel = URIUtils::GetFileName(m_vecItems->m_strPath);
497 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
499 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
500 SET_CONTROL_LABEL(CONTROL_BTNSHOWMODE, g_localizeStrings.Get(16100 + watchMode));
502 SET_CONTROL_SELECTED(GetID(), CONTROL_BTNSHOWALL, watchMode != VIDEO_SHOW_ALL);
504 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
506 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNFLATTEN, g_settings.m_bMyVideoNavFlatten);
509 /// \brief Search for names, genres, artists, directors, and plots with search string \e strSearch in the
510 /// \brief video databases and return the found \e items
511 /// \param strSearch The search string
512 /// \param items Items Found
513 void CGUIWindowVideoNav::DoSearch(const CStdString& strSearch, CFileItemList& items)
515 CFileItemList tempItems;
516 CStdString strGenre = g_localizeStrings.Get(515); // Genre
517 CStdString strActor = g_localizeStrings.Get(20337); // Actor
518 CStdString strDirector = g_localizeStrings.Get(20339); // Director
519 CStdString strMovie = g_localizeStrings.Get(20338); // Movie
522 m_database.GetMoviesByName(strSearch, tempItems);
523 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20338) + "] ", items);
525 m_database.GetEpisodesByName(strSearch, tempItems);
526 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20359) + "] ", items);
528 m_database.GetTvShowsByName(strSearch, tempItems);
529 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20364) + "] ", items);
531 m_database.GetMusicVideosByName(strSearch, tempItems);
532 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20391) + "] ", items);
534 m_database.GetMusicVideosByAlbum(strSearch, tempItems);
535 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(558) + "] ", items);
537 // get matching genres
538 m_database.GetMovieGenresByName(strSearch, tempItems);
539 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20342) + "] ", items);
541 m_database.GetTvShowGenresByName(strSearch, tempItems);
542 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20343) + "] ", items);
544 m_database.GetMusicVideoGenresByName(strSearch, tempItems);
545 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20389) + "] ", items);
548 m_database.GetMovieActorsByName(strSearch, tempItems);
549 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20342) + "] ", items);
551 m_database.GetTvShowsActorsByName(strSearch, tempItems);
552 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20343) + "] ", items);
554 m_database.GetMusicVideoArtistsByName(strSearch, tempItems);
555 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20389) + "] ", items);
558 m_database.GetMovieDirectorsByName(strSearch, tempItems);
559 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20342) + "] ", items);
561 m_database.GetTvShowsDirectorsByName(strSearch, tempItems);
562 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20343) + "] ", items);
564 m_database.GetMusicVideoDirectorsByName(strSearch, tempItems);
565 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20389) + "] ", items);
568 m_database.GetEpisodesByPlot(strSearch, tempItems);
569 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20365) + "] ", items);
571 m_database.GetMoviesByPlot(strSearch, tempItems);
572 AppendAndClearSearchItems(tempItems, "[" + strMovie + " " + g_localizeStrings.Get(207) + "] ", items);
575 void CGUIWindowVideoNav::PlayItem(int iItem)
577 // unlike additemtoplaylist, we need to check the items here
578 // before calling it since the current playlist will be stopped
581 // root is not allowed
582 if (m_vecItems->IsVirtualDirectoryRoot())
585 CGUIWindowVideoBase::PlayItem(iItem);
588 void CGUIWindowVideoNav::OnInfo(CFileItem* pItem, ADDON::ScraperPtr& scraper)
590 m_database.Open(); // since we can be called from the music library without being inited
591 if (pItem->IsVideoDb())
592 scraper = m_database.GetScraperForPath(pItem->GetVideoInfoTag()->m_strPath);
595 CStdString strPath,strFile;
596 URIUtils::Split(pItem->m_strPath,strPath,strFile);
597 scraper = m_database.GetScraperForPath(strPath);
600 CGUIWindowVideoBase::OnInfo(pItem,scraper);
603 bool CGUIWindowVideoNav::CanDelete(const CStdString& strPath)
606 CVideoDatabaseDirectory::GetQueryParams(strPath,params);
608 if (params.GetMovieId() != -1 ||
609 params.GetEpisodeId() != -1 ||
610 params.GetMVideoId() != -1 ||
611 (params.GetTvShowId() != -1 && params.GetSeason() == -1
612 && !CVideoDatabaseDirectory::IsAllItem(strPath)))
618 void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
620 if (m_vecItems->IsParentFolder())
623 if (!m_vecItems->IsVideoDb())
625 if (!pItem->m_strPath.Equals("newsmartplaylist://video") &&
626 !pItem->m_strPath.Equals("special://videoplaylists/") &&
627 !pItem->m_strPath.Equals("sources://video/"))
628 CGUIWindowVideoBase::OnDeleteItem(pItem);
630 else if (pItem->m_strPath.Left(14).Equals("videodb://1/7/") &&
631 pItem->m_strPath.size() > 14 && pItem->m_bIsFolder)
633 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
634 pDialog->SetLine(0, g_localizeStrings.Get(432));
636 strLabel.Format(g_localizeStrings.Get(433),pItem->GetLabel());
637 pDialog->SetLine(1, strLabel);
638 pDialog->SetLine(2, "");;
640 if (pDialog->IsConfirmed())
643 CDirectory::GetDirectory(pItem->m_strPath,items,"",false,false,DIR_CACHE_ONCE,true,true);
644 for (int i=0;i<items.Size();++i)
645 OnDeleteItem(items[i]);
647 CVideoDatabaseDirectory dir;
649 dir.GetQueryParams(pItem->m_strPath,params);
650 m_database.DeleteSet(params.GetSetId());
655 if (!DeleteItem(pItem.get()))
658 CStdString strDeletePath;
659 if (pItem->m_bIsFolder)
660 strDeletePath=pItem->GetVideoInfoTag()->m_strPath;
662 strDeletePath=pItem->GetVideoInfoTag()->m_strFileNameAndPath;
664 if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
666 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
667 if (strDeletePath.Right(9).Equals("VIDEO_TS/"))
669 URIUtils::RemoveSlashAtEnd(strDeletePath);
670 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
673 if (URIUtils::HasSlashAtEnd(strDeletePath))
674 pItem->m_bIsFolder=true;
676 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
677 CUtil::SupportsFileOperations(strDeletePath))
679 pItem->m_strPath = strDeletePath;
680 CGUIWindowVideoBase::OnDeleteItem(pItem);
684 CUtil::DeleteVideoDatabaseDirectoryCache();
687 bool CGUIWindowVideoNav::DeleteItem(CFileItem* pItem, bool bUnavailable /* = false */)
689 if (!pItem->HasVideoInfoTag() || !CanDelete(pItem->m_strPath))
692 VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES;
693 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty())
694 iType = VIDEODB_CONTENT_TVSHOWS;
695 if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iSeason > -1 && !pItem->m_bIsFolder)
696 iType = VIDEODB_CONTENT_EPISODES;
697 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strArtist.IsEmpty())
698 iType = VIDEODB_CONTENT_MUSICVIDEOS;
700 // dont allow update while scanning
701 CGUIDialogVideoScan* pDialogScan = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
702 if (pDialogScan && pDialogScan->IsScanning())
704 CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
709 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
712 if (iType == VIDEODB_CONTENT_MOVIES)
713 pDialog->SetHeading(432);
714 if (iType == VIDEODB_CONTENT_EPISODES)
715 pDialog->SetHeading(20362);
716 if (iType == VIDEODB_CONTENT_TVSHOWS)
717 pDialog->SetHeading(20363);
718 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
719 pDialog->SetHeading(20392);
723 pDialog->SetLine(0, g_localizeStrings.Get(662));
724 pDialog->SetLine(1, g_localizeStrings.Get(663));
725 pDialog->SetLine(2, "");;
731 strLine.Format(g_localizeStrings.Get(433),pItem->GetLabel());
732 pDialog->SetLine(0, strLine);
733 pDialog->SetLine(1, "");
734 pDialog->SetLine(2, "");;
738 if (!pDialog->IsConfirmed())
742 CVideoDatabase database;
745 database.GetFilePathById(pItem->GetVideoInfoTag()->m_iDbId, path, iType);
748 if (iType == VIDEODB_CONTENT_MOVIES)
749 database.DeleteMovie(path);
750 if (iType == VIDEODB_CONTENT_EPISODES)
751 database.DeleteEpisode(path, pItem->GetVideoInfoTag()->m_iDbId);
752 if (iType == VIDEODB_CONTENT_TVSHOWS)
753 database.DeleteTvShow(path);
754 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
755 database.DeleteMusicVideo(path);
757 if (iType == VIDEODB_CONTENT_TVSHOWS)
758 database.SetPathHash(path,"");
761 CStdString strDirectory;
762 URIUtils::GetDirectory(path,strDirectory);
763 database.SetPathHash(strDirectory,"");
769 void CGUIWindowVideoNav::OnPrepareFileItems(CFileItemList &items)
771 CGUIWindowVideoBase::OnPrepareFileItems(items);
775 CVideoDatabaseDirectory dir;
776 dir.GetQueryParams(items.m_strPath,params);
777 if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
778 CGUIWindowMusicNav::SetupFanart(items);
780 NODE_TYPE node = dir.GetDirectoryChildType(items.m_strPath);
782 // now filter as necessary
783 bool filterWatched=false;
784 if (node == NODE_TYPE_EPISODES
785 || node == NODE_TYPE_SEASONS
786 || node == NODE_TYPE_TITLE_MOVIES
787 || node == NODE_TYPE_TITLE_TVSHOWS
788 || node == NODE_TYPE_TITLE_MUSICVIDEOS
789 || node == NODE_TYPE_RECENTLY_ADDED_EPISODES
790 || node == NODE_TYPE_RECENTLY_ADDED_MOVIES
791 || node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
792 filterWatched = true;
793 if (!items.IsVideoDb())
794 filterWatched = true;
795 if (items.IsSmartPlayList() && items.GetContent() == "tvshows")
796 node = NODE_TYPE_TITLE_TVSHOWS; // so that the check below works
798 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
800 for (int i = 0; i < items.Size(); i++)
802 CFileItemPtr item = items.Get(i);
803 if(item->HasVideoInfoTag() && (node == NODE_TYPE_TITLE_TVSHOWS || node == NODE_TYPE_SEASONS))
805 if (watchMode == VIDEO_SHOW_UNWATCHED)
806 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("unwatchedepisodes");
807 if (watchMode == VIDEO_SHOW_WATCHED)
808 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("watchedepisodes");
809 item->SetProperty("numepisodes", item->GetVideoInfoTag()->m_iEpisode);
814 if((watchMode==VIDEO_SHOW_WATCHED && item->GetVideoInfoTag()->m_playCount== 0)
815 || (watchMode==VIDEO_SHOW_UNWATCHED && item->GetVideoInfoTag()->m_playCount > 0))
824 void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
827 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
828 item = m_vecItems->Get(itemNumber);
830 CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons);
832 if (item && item->GetPropertyBOOL("pluginreplacecontextitems"))
835 CVideoDatabaseDirectory dir;
836 NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->m_strPath);
840 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
841 if (pScanDlg && pScanDlg->IsScanning())
842 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
844 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
846 else if (m_vecItems->m_strPath.Equals("sources://video/"))
848 // get the usual shares
849 CGUIDialogContextMenu::GetContextButtons("video", item, buttons);
850 // add scan button somewhere here
851 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
852 if (pScanDlg && pScanDlg->IsScanning())
853 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning
854 if (!item->IsDVD() && item->m_strPath != "add" &&
855 (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
857 CVideoDatabase database;
859 ADDON::ScraperPtr info = database.GetScraperForPath(item->m_strPath);
861 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
863 if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
865 if (info && info->Content() != CONTENT_NONE)
866 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
868 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
872 if (info && (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning())))
873 buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
878 ADDON::ScraperPtr info;
879 VIDEO::SScanSettings settings;
880 GetScraperForItem(item.get(), info, settings);
882 if (info && info->Content() == CONTENT_TVSHOWS)
883 buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352);
884 else if (info && info->Content() == CONTENT_MUSICVIDEOS)
885 buttons.Add(CONTEXT_BUTTON_INFO,20393);
886 else if (!item->m_bIsFolder && !item->m_strPath.Left(19).Equals("newsmartplaylist://"))
887 buttons.Add(CONTEXT_BUTTON_INFO, 13346);
889 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strArtist.IsEmpty())
891 CMusicDatabase database;
893 if (database.GetArtistByName(item->GetVideoInfoTag()->m_strArtist) > -1)
894 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396);
896 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0)
898 CMusicDatabase database;
900 if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1)
901 buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397);
903 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 &&
904 item->GetVideoInfoTag()->m_strArtist.size() > 0 &&
905 item->GetVideoInfoTag()->m_strTitle.size() > 0)
907 CMusicDatabase database;
909 if (database.GetSongByArtistAndAlbumAndTitle(item->GetVideoInfoTag()->m_strArtist,
910 item->GetVideoInfoTag()->m_strAlbum,
911 item->GetVideoInfoTag()->m_strTitle) > -1)
913 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398);
916 if (!item->IsParentFolder())
918 // can we update the database?
919 if (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
921 if (node == NODE_TYPE_TITLE_TVSHOWS)
923 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
924 if (pScanDlg && pScanDlg->IsScanning())
925 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
927 buttons.Add(CONTEXT_BUTTON_UPDATE_TVSHOW, 13349);
929 if (!item->IsPlugin() && !item->IsLiveTV() && !item->IsAddonsPath() &&
930 item->m_strPath != "sources://video/" && item->m_strPath != "special://videoplaylists/")
932 if (item->m_bIsFolder)
934 // Have both options for folders since we don't know whether all childs are watched/unwatched
935 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
936 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
940 if (item->GetOverlayImage().Equals("OverlayWatched.png"))
941 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
943 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
946 if ((node == NODE_TYPE_TITLE_TVSHOWS) ||
947 (item->IsVideoDb() && item->HasVideoInfoTag() && !item->m_bIsFolder))
949 buttons.Add(CONTEXT_BUTTON_EDIT, 16105); //Edit Title
951 if (m_database.HasContent(VIDEODB_CONTENT_TVSHOWS) && item->HasVideoInfoTag() &&
952 !item->m_bIsFolder && item->GetVideoInfoTag()->m_iEpisode == -1 &&
953 item->GetVideoInfoTag()->m_strArtist.IsEmpty() && item->GetVideoInfoTag()->m_iDbId >= 0) // movie entry
955 if (m_database.IsLinkedToTvshow(item->GetVideoInfoTag()->m_iDbId))
956 buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE,20385);
957 buttons.Add(CONTEXT_BUTTON_LINK_MOVIE,20384);
960 if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
961 buttons.Add(CONTEXT_BUTTON_SET_SEASON_THUMB, 20371);
963 if (item->m_strPath.Left(14).Equals("videodb://1/7/") && item->m_strPath.size() > 14 && item->m_bIsFolder) // sets
965 buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
966 buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_THUMB, 20435);
967 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
970 if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder)
972 if (m_vecItems->m_strPath.Left(11).Equals("videodb://3")) // mvids
973 buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
975 buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
977 if (item->IsVideoDb() && item->HasVideoInfoTag() &&
978 (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS))
980 if (info && info->Content() == CONTENT_TVSHOWS)
982 if(item->GetVideoInfoTag()->m_iBookmarkId != -1 &&
983 item->GetVideoInfoTag()->m_iBookmarkId != 0)
985 buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
988 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
991 // this should ideally be non-contextual (though we need some context for non-tv show node I guess)
992 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
993 if (pScanDlg && pScanDlg->IsScanning())
995 if (node != NODE_TYPE_TITLE_TVSHOWS)
996 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
999 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
1002 if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
1003 { // non-video db items, file operations are allowed
1004 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
1005 CUtil::SupportsFileOperations(item->m_strPath))
1007 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
1008 buttons.Add(CONTEXT_BUTTON_RENAME, 118);
1010 // add "Set/Change content" to folders
1011 if (item->m_bIsFolder && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
1013 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1014 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
1016 if (info && info->Content() != CONTENT_NONE)
1017 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
1019 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
1023 if (item->IsPlugin() || item->m_strPath.Left(9).Equals("script://") || m_vecItems->IsPlugin())
1024 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
1027 CGUIWindowVideoBase::GetNonContextButtons(itemNumber, buttons);
1030 bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
1033 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
1034 item = m_vecItems->Get(itemNumber);
1035 if (CGUIDialogContextMenu::OnContextButton("video", item, button))
1037 //TODO should we search DB for entries from plugins?
1038 if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin()
1039 && !item->IsLiveTV() &&!item->IsRSS())
1041 OnUnAssignContent(item->m_strPath,20375,20340,20341);
1043 Update(m_vecItems->m_strPath);
1048 case CONTEXT_BUTTON_EDIT:
1049 UpdateVideoTitle(item.get());
1050 CUtil::DeleteVideoDatabaseDirectoryCache();
1051 Update(m_vecItems->m_strPath);
1054 case CONTEXT_BUTTON_SET_SEASON_THUMB:
1055 case CONTEXT_BUTTON_SET_ACTOR_THUMB:
1056 case CONTEXT_BUTTON_SET_ARTIST_THUMB:
1057 case CONTEXT_BUTTON_SET_MOVIESET_THUMB:
1059 // Grab the thumbnails from the web
1061 CFileItemList items;
1062 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,"imdbthumbs",strPath);
1063 CFileItemPtr cacheItem(new CFileItem(strPath,true));
1064 CFileUtils::DeleteItem(cacheItem,true);
1065 XFILE::CDirectory::Create(strPath);
1066 CFileItemPtr noneitem(new CFileItem("thumb://None", false));
1067 CStdString cachedThumb = m_vecItems->Get(itemNumber)->GetCachedSeasonThumb();
1068 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1069 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedActorThumb();
1070 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1071 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedArtistThumb();
1072 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1073 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedVideoThumb();
1074 if (CFile::Exists(cachedThumb))
1076 CFileItemPtr item(new CFileItem("thumb://Current", false));
1077 item->SetThumbnailImage(cachedThumb);
1078 item->SetLabel(g_localizeStrings.Get(20016));
1081 noneitem->SetIconImage("DefaultFolder.png");
1082 noneitem->SetLabel(g_localizeStrings.Get(20018));
1084 vector<CStdString> thumbs;
1085 if (button != CONTEXT_BUTTON_SET_ARTIST_THUMB)
1088 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1089 m_database.GetTvShowInfo("",tag,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId);
1091 tag = *m_vecItems->Get(itemNumber)->GetVideoInfoTag();
1092 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1093 tag.m_strPictureURL.GetThumbURLs(thumbs, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iSeason);
1095 tag.m_strPictureURL.GetThumbURLs(thumbs);
1097 for (unsigned int i = 0; i < thumbs.size(); i++)
1099 CStdString strItemPath;
1100 strItemPath.Format("thumb://Remote%i",i);
1101 CFileItemPtr item(new CFileItem(strItemPath, false));
1102 item->SetThumbnailImage(thumbs[i]);
1103 item->SetIconImage("DefaultPicture.png");
1104 item->SetLabel(g_localizeStrings.Get(20015));
1107 // TODO: Do we need to clear the cached image?
1108 // CTextureCache::Get().ClearCachedImage(thumbs[i]);
1113 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1115 CStdString picturePath;
1117 CStdString strPath = m_vecItems->Get(itemNumber)->m_strPath;
1118 URIUtils::RemoveSlashAtEnd(strPath);
1120 int nPos=strPath.ReverseFind("/");
1123 // try to guess where the user should start
1124 // browsing for the artist thumb
1125 CMusicDatabase database;
1127 long idArtist=database.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
1128 database.GetArtistPath(idArtist, picturePath);
1131 CStdString strThumb;
1132 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1133 if (XFILE::CFile::Exists(strThumb))
1135 CFileItemPtr pItem(new CFileItem(strThumb,false));
1136 pItem->SetLabel(g_localizeStrings.Get(20017));
1137 pItem->SetThumbnailImage(strThumb);
1142 noneitem->SetIconImage("DefaultArtist.png");
1145 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1147 CStdString picturePath;
1148 CStdString strThumb;
1149 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1150 if (XFILE::CFile::Exists(strThumb))
1152 CFileItemPtr pItem(new CFileItem(strThumb,false));
1153 pItem->SetLabel(g_localizeStrings.Get(20017));
1154 pItem->SetThumbnailImage(strThumb);
1159 noneitem->SetIconImage("DefaultActor.png");
1162 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1163 noneitem->SetIconImage("DefaultVideo.png");
1166 items.Add(noneitem);
1168 VECSOURCES sources=g_settings.m_videoSources;
1169 g_mediaManager.GetLocalDrives(sources);
1171 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources,
1172 g_localizeStrings.Get(20019), result))
1174 return false; // user cancelled
1177 if (result == "thumb://Current")
1178 return false; // user chose the one they have
1180 // delete the thumbnail if that's what the user wants, else overwrite with the
1182 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1183 if (result.Left(14) == "thumb://Remote")
1185 int number = atoi(result.Mid(14));
1186 CFile::Cache(thumbs[number], cachedThumb);
1188 if (result == "thumb://None")
1189 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1191 CFile::Cache(result,cachedThumb);
1193 CUtil::DeleteVideoDatabaseDirectoryCache();
1194 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
1195 g_windowManager.SendMessage(msg);
1196 Update(m_vecItems->m_strPath);
1200 case CONTEXT_BUTTON_UPDATE_LIBRARY:
1205 case CONTEXT_BUTTON_UNLINK_MOVIE:
1207 OnLinkMovieToTvShow(itemNumber, true);
1208 Update(m_vecItems->m_strPath);
1211 case CONTEXT_BUTTON_LINK_MOVIE:
1213 OnLinkMovieToTvShow(itemNumber, false);
1216 case CONTEXT_BUTTON_GO_TO_ARTIST:
1219 CMusicDatabase database;
1221 strPath.Format("musicdb://2/%ld/",database.GetArtistByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist));
1222 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1225 case CONTEXT_BUTTON_GO_TO_ALBUM:
1228 CMusicDatabase database;
1230 strPath.Format("musicdb://3/%ld/",database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum));
1231 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1234 case CONTEXT_BUTTON_PLAY_OTHER:
1236 CMusicDatabase database;
1239 if (database.GetSongById(database.GetSongByArtistAndAlbumAndTitle(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum,
1240 m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle),
1243 g_application.getApplicationMessenger().PlayFile(song);
1248 case CONTEXT_BUTTON_UNLINK_BOOKMARK:
1251 m_database.DeleteBookMarkForEpisode(*m_vecItems->Get(itemNumber)->GetVideoInfoTag());
1253 CUtil::DeleteVideoDatabaseDirectoryCache();
1254 Update(m_vecItems->m_strPath);
1262 return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
1265 void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove)
1271 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1273 for (unsigned int i=0;i<ids.size();++i)
1276 m_database.GetTvShowInfo("",tag,ids[i]);
1277 CFileItemPtr show(new CFileItem(tag));
1283 m_database.GetTvShowsNav("videodb://2/2",list);
1285 // remove already linked shows
1287 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1289 for (int i=0;i<list.Size();)
1292 for (j=0;j<ids.size();++j)
1294 if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j])
1297 if (j == ids.size())
1303 int iSelectedLabel = 0;
1304 if (list.Size() > 1)
1306 list.Sort(g_guiSettings.GetBool("filelists.ignorethewhensorting") ? SORT_METHOD_LABEL_IGNORE_THE : SORT_METHOD_LABEL, SORT_ORDER_ASC);
1307 CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
1309 pDialog->SetItems(&list);
1310 pDialog->SetHeading(20356);
1312 iSelectedLabel = pDialog->GetSelectedLabel();
1314 if (iSelectedLabel > -1)
1316 m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,
1317 list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove);
1318 CUtil::DeleteVideoDatabaseDirectoryCache();
1322 bool CGUIWindowVideoNav::OnClick(int iItem)
1324 CFileItemPtr item = m_vecItems->Get(iItem);
1325 if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
1327 if (!DeleteItem(item.get(), true))
1331 m_vecItems->RemoveDiscCache(GetID());
1332 Update(m_vecItems->m_strPath);
1333 m_viewControl.SetSelectedItem(iItem);
1337 return CGUIWindowVideoBase::OnClick(iItem);
1340 CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
1342 if (dir.Equals("MovieGenres"))
1343 return "videodb://1/1/";
1344 else if (dir.Equals("MovieTitles"))
1345 return "videodb://1/2/";
1346 else if (dir.Equals("MovieYears"))
1347 return "videodb://1/3/";
1348 else if (dir.Equals("MovieActors"))
1349 return "videodb://1/4/";
1350 else if (dir.Equals("MovieDirectors"))
1351 return "videodb://1/5/";
1352 else if (dir.Equals("MovieStudios"))
1353 return "videodb://1/6/";
1354 else if (dir.Equals("MovieSets"))
1355 return "videodb://1/7/";
1356 else if (dir.Equals("MovieCountries"))
1357 return "videodb://1/8/";
1358 else if (dir.Equals("Movies"))
1359 return "videodb://1/";
1360 else if (dir.Equals("TvShowGenres"))
1361 return "videodb://2/1/";
1362 else if (dir.Equals("TvShowTitles"))
1363 return "videodb://2/2/";
1364 else if (dir.Equals("TvShowYears"))
1365 return "videodb://2/3/";
1366 else if (dir.Equals("TvShowActors"))
1367 return "videodb://2/4/";
1368 else if (dir.Equals("TvShowStudios"))
1369 return "videodb://2/5/";
1370 else if (dir.Equals("TvShows"))
1371 return "videodb://2/";
1372 else if (dir.Equals("MusicVideoGenres"))
1373 return "videodb://3/1/";
1374 else if (dir.Equals("MusicVideoTitles"))
1375 return "videodb://3/2/";
1376 else if (dir.Equals("MusicVideoYears"))
1377 return "videodb://3/3/";
1378 else if (dir.Equals("MusicVideoArtists"))
1379 return "videodb://3/4/";
1380 else if (dir.Equals("MusicVideoDirectors"))
1381 return "videodb://3/5/";
1382 else if (dir.Equals("MusicVideoStudios"))
1383 return "videodb://3/6/";
1384 else if (dir.Equals("MusicVideos"))
1385 return "videodb://3/";
1386 else if (dir.Equals("RecentlyAddedMovies"))
1387 return "videodb://4/";
1388 else if (dir.Equals("RecentlyAddedEpisodes"))
1389 return "videodb://5/";
1390 else if (dir.Equals("RecentlyAddedMusicVideos"))
1391 return "videodb://6/";
1392 else if (dir.Equals("Files"))
1393 return "sources://video/";
1394 return CGUIWindowVideoBase::GetStartFolder(dir);