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 if (content.IsEmpty())
418 items.SetContent("files");
421 items.SetContent(content);
423 bool clean = (g_guiSettings.GetBool("myvideos.cleanstrings") &&
424 !items.IsVirtualDirectoryRoot() &&
425 m_stackingAvailable);
427 if (!content.IsEmpty())
429 for (int i = 0; i < items.Size(); i++)
431 CFileItemPtr pItem = items[i];
433 if (m_database.GetItemForPath(content, pItem->m_strPath, item))
434 { // copy info across
435 pItem->UpdateInfo(item);
436 pItem->m_strPath = item.m_strPath;
437 // if we switch from a file to a folder item it means we really shouldn't be sorting files and
438 // folders separately
439 if (pItem->m_bIsFolder != item.m_bIsFolder)
440 items.SetSortIgnoreFolders(true);
441 pItem->m_bIsFolder = item.m_bIsFolder;
446 pItem->CleanString();
452 for (int i = 0; i < items.Size(); i++)
454 CFileItemPtr pItem = items[i];
455 int playCount = m_database.GetPlayCount(*pItem);
457 pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, playCount > 0);
459 pItem->CleanString();
464 void CGUIWindowVideoNav::UpdateButtons()
466 CGUIWindowVideoBase::UpdateButtons();
468 // Update object count
469 int iItems = m_vecItems->Size();
472 // check for parent dir and "all" items
473 // should always be the first two items
474 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
476 CFileItemPtr pItem = m_vecItems->Get(i);
477 if (pItem->IsParentFolder()) iItems--;
478 if (pItem->m_strPath.Left(4).Equals("/-1/")) iItems--;
481 if (m_vecItems->Size() > 2 &&
482 m_vecItems->Get(m_vecItems->Size()-1)->m_strPath.Left(4).Equals("/-1/"))
486 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
487 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
489 // set the filter label
493 if (m_vecItems->m_strPath.Equals("special://videoplaylists/"))
494 strLabel = g_localizeStrings.Get(136);
496 else if (m_vecItems->IsPlayList())
498 // get playlist name from path
500 URIUtils::Split(m_vecItems->m_strPath, strDummy, strLabel);
502 else if (m_vecItems->m_strPath.Equals("sources://video/"))
503 strLabel = g_localizeStrings.Get(744);
504 // everything else is from a videodb:// path
505 else if (m_vecItems->IsVideoDb())
507 CVideoDatabaseDirectory dir;
508 dir.GetLabel(m_vecItems->m_strPath, strLabel);
511 strLabel = URIUtils::GetFileName(m_vecItems->m_strPath);
513 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
515 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
516 SET_CONTROL_LABEL(CONTROL_BTNSHOWMODE, g_localizeStrings.Get(16100 + watchMode));
518 SET_CONTROL_SELECTED(GetID(), CONTROL_BTNSHOWALL, watchMode != VIDEO_SHOW_ALL);
520 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
522 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNFLATTEN, g_settings.m_bMyVideoNavFlatten);
525 /// \brief Search for names, genres, artists, directors, and plots with search string \e strSearch in the
526 /// \brief video databases and return the found \e items
527 /// \param strSearch The search string
528 /// \param items Items Found
529 void CGUIWindowVideoNav::DoSearch(const CStdString& strSearch, CFileItemList& items)
531 CFileItemList tempItems;
532 CStdString strGenre = g_localizeStrings.Get(515); // Genre
533 CStdString strActor = g_localizeStrings.Get(20337); // Actor
534 CStdString strDirector = g_localizeStrings.Get(20339); // Director
535 CStdString strMovie = g_localizeStrings.Get(20338); // Movie
538 m_database.GetMoviesByName(strSearch, tempItems);
539 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20338) + "] ", items);
541 m_database.GetEpisodesByName(strSearch, tempItems);
542 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20359) + "] ", items);
544 m_database.GetTvShowsByName(strSearch, tempItems);
545 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20364) + "] ", items);
547 m_database.GetMusicVideosByName(strSearch, tempItems);
548 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20391) + "] ", items);
550 m_database.GetMusicVideosByAlbum(strSearch, tempItems);
551 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(558) + "] ", items);
553 // get matching genres
554 m_database.GetMovieGenresByName(strSearch, tempItems);
555 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20342) + "] ", items);
557 m_database.GetTvShowGenresByName(strSearch, tempItems);
558 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20343) + "] ", items);
560 m_database.GetMusicVideoGenresByName(strSearch, tempItems);
561 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20389) + "] ", items);
564 m_database.GetMovieActorsByName(strSearch, tempItems);
565 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20342) + "] ", items);
567 m_database.GetTvShowsActorsByName(strSearch, tempItems);
568 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20343) + "] ", items);
570 m_database.GetMusicVideoArtistsByName(strSearch, tempItems);
571 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20389) + "] ", items);
574 m_database.GetMovieDirectorsByName(strSearch, tempItems);
575 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20342) + "] ", items);
577 m_database.GetTvShowsDirectorsByName(strSearch, tempItems);
578 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20343) + "] ", items);
580 m_database.GetMusicVideoDirectorsByName(strSearch, tempItems);
581 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20389) + "] ", items);
584 m_database.GetEpisodesByPlot(strSearch, tempItems);
585 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20365) + "] ", items);
587 m_database.GetMoviesByPlot(strSearch, tempItems);
588 AppendAndClearSearchItems(tempItems, "[" + strMovie + " " + g_localizeStrings.Get(207) + "] ", items);
591 void CGUIWindowVideoNav::PlayItem(int iItem)
593 // unlike additemtoplaylist, we need to check the items here
594 // before calling it since the current playlist will be stopped
597 // root is not allowed
598 if (m_vecItems->IsVirtualDirectoryRoot())
601 CGUIWindowVideoBase::PlayItem(iItem);
604 void CGUIWindowVideoNav::OnInfo(CFileItem* pItem, ADDON::ScraperPtr& scraper)
606 m_database.Open(); // since we can be called from the music library without being inited
607 if (pItem->IsVideoDb())
608 scraper = m_database.GetScraperForPath(pItem->GetVideoInfoTag()->m_strPath);
611 CStdString strPath,strFile;
612 URIUtils::Split(pItem->m_strPath,strPath,strFile);
613 scraper = m_database.GetScraperForPath(strPath);
616 CGUIWindowVideoBase::OnInfo(pItem,scraper);
619 bool CGUIWindowVideoNav::CanDelete(const CStdString& strPath)
622 CVideoDatabaseDirectory::GetQueryParams(strPath,params);
624 if (params.GetMovieId() != -1 ||
625 params.GetEpisodeId() != -1 ||
626 params.GetMVideoId() != -1 ||
627 (params.GetTvShowId() != -1 && params.GetSeason() == -1
628 && !CVideoDatabaseDirectory::IsAllItem(strPath)))
634 void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
636 if (m_vecItems->IsParentFolder())
639 if (!m_vecItems->IsVideoDb())
641 if (!pItem->m_strPath.Equals("newsmartplaylist://video") &&
642 !pItem->m_strPath.Equals("special://videoplaylists/") &&
643 !pItem->m_strPath.Equals("sources://video/"))
644 CGUIWindowVideoBase::OnDeleteItem(pItem);
646 else if (pItem->m_strPath.Left(14).Equals("videodb://1/7/") &&
647 pItem->m_strPath.size() > 14 && pItem->m_bIsFolder)
649 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
650 pDialog->SetLine(0, g_localizeStrings.Get(432));
652 strLabel.Format(g_localizeStrings.Get(433),pItem->GetLabel());
653 pDialog->SetLine(1, strLabel);
654 pDialog->SetLine(2, "");;
656 if (pDialog->IsConfirmed())
659 CDirectory::GetDirectory(pItem->m_strPath,items,"",false,false,DIR_CACHE_ONCE,true,true);
660 for (int i=0;i<items.Size();++i)
661 OnDeleteItem(items[i]);
663 CVideoDatabaseDirectory dir;
665 dir.GetQueryParams(pItem->m_strPath,params);
666 m_database.DeleteSet(params.GetSetId());
671 if (!DeleteItem(pItem.get()))
674 CStdString strDeletePath;
675 if (pItem->m_bIsFolder)
676 strDeletePath=pItem->GetVideoInfoTag()->m_strPath;
678 strDeletePath=pItem->GetVideoInfoTag()->m_strFileNameAndPath;
680 if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
682 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
683 if (strDeletePath.Right(9).Equals("VIDEO_TS/"))
685 URIUtils::RemoveSlashAtEnd(strDeletePath);
686 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
689 if (URIUtils::HasSlashAtEnd(strDeletePath))
690 pItem->m_bIsFolder=true;
692 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
693 CUtil::SupportsFileOperations(strDeletePath))
695 pItem->m_strPath = strDeletePath;
696 CGUIWindowVideoBase::OnDeleteItem(pItem);
700 CUtil::DeleteVideoDatabaseDirectoryCache();
703 bool CGUIWindowVideoNav::DeleteItem(CFileItem* pItem, bool bUnavailable /* = false */)
705 if (!pItem->HasVideoInfoTag() || !CanDelete(pItem->m_strPath))
708 VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES;
709 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty())
710 iType = VIDEODB_CONTENT_TVSHOWS;
711 if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iSeason > -1 && !pItem->m_bIsFolder)
712 iType = VIDEODB_CONTENT_EPISODES;
713 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strArtist.IsEmpty())
714 iType = VIDEODB_CONTENT_MUSICVIDEOS;
716 // dont allow update while scanning
717 CGUIDialogVideoScan* pDialogScan = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
718 if (pDialogScan && pDialogScan->IsScanning())
720 CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
725 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
728 if (iType == VIDEODB_CONTENT_MOVIES)
729 pDialog->SetHeading(432);
730 if (iType == VIDEODB_CONTENT_EPISODES)
731 pDialog->SetHeading(20362);
732 if (iType == VIDEODB_CONTENT_TVSHOWS)
733 pDialog->SetHeading(20363);
734 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
735 pDialog->SetHeading(20392);
739 pDialog->SetLine(0, g_localizeStrings.Get(662));
740 pDialog->SetLine(1, g_localizeStrings.Get(663));
741 pDialog->SetLine(2, "");;
747 strLine.Format(g_localizeStrings.Get(433),pItem->GetLabel());
748 pDialog->SetLine(0, strLine);
749 pDialog->SetLine(1, "");
750 pDialog->SetLine(2, "");;
754 if (!pDialog->IsConfirmed())
758 CVideoDatabase database;
761 database.GetFilePathById(pItem->GetVideoInfoTag()->m_iDbId, path, iType);
764 if (iType == VIDEODB_CONTENT_MOVIES)
765 database.DeleteMovie(path);
766 if (iType == VIDEODB_CONTENT_EPISODES)
767 database.DeleteEpisode(path, pItem->GetVideoInfoTag()->m_iDbId);
768 if (iType == VIDEODB_CONTENT_TVSHOWS)
769 database.DeleteTvShow(path);
770 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
771 database.DeleteMusicVideo(path);
773 if (iType == VIDEODB_CONTENT_TVSHOWS)
774 database.SetPathHash(path,"");
777 CStdString strDirectory;
778 URIUtils::GetDirectory(path,strDirectory);
779 database.SetPathHash(strDirectory,"");
785 void CGUIWindowVideoNav::OnPrepareFileItems(CFileItemList &items)
787 CGUIWindowVideoBase::OnPrepareFileItems(items);
791 CVideoDatabaseDirectory dir;
792 dir.GetQueryParams(items.m_strPath,params);
793 if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
794 CGUIWindowMusicNav::SetupFanart(items);
796 NODE_TYPE node = dir.GetDirectoryChildType(items.m_strPath);
798 // now filter as necessary
799 bool filterWatched=false;
800 if (node == NODE_TYPE_EPISODES
801 || node == NODE_TYPE_SEASONS
802 || node == NODE_TYPE_TITLE_MOVIES
803 || node == NODE_TYPE_TITLE_TVSHOWS
804 || node == NODE_TYPE_TITLE_MUSICVIDEOS
805 || node == NODE_TYPE_RECENTLY_ADDED_EPISODES
806 || node == NODE_TYPE_RECENTLY_ADDED_MOVIES
807 || node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
808 filterWatched = true;
809 if (!items.IsVideoDb())
810 filterWatched = true;
811 if (items.IsSmartPlayList() && items.GetContent() == "tvshows")
812 node = NODE_TYPE_TITLE_TVSHOWS; // so that the check below works
814 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
816 for (int i = 0; i < items.Size(); i++)
818 CFileItemPtr item = items.Get(i);
819 if(item->HasVideoInfoTag() && (node == NODE_TYPE_TITLE_TVSHOWS || node == NODE_TYPE_SEASONS))
821 if (watchMode == VIDEO_SHOW_UNWATCHED)
822 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("unwatchedepisodes");
823 if (watchMode == VIDEO_SHOW_WATCHED)
824 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("watchedepisodes");
825 item->SetProperty("numepisodes", item->GetVideoInfoTag()->m_iEpisode);
830 if((watchMode==VIDEO_SHOW_WATCHED && item->GetVideoInfoTag()->m_playCount== 0)
831 || (watchMode==VIDEO_SHOW_UNWATCHED && item->GetVideoInfoTag()->m_playCount > 0))
840 void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
843 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
844 item = m_vecItems->Get(itemNumber);
846 CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons);
848 if (item && item->GetPropertyBOOL("pluginreplacecontextitems"))
851 CVideoDatabaseDirectory dir;
852 NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->m_strPath);
856 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
857 if (pScanDlg && pScanDlg->IsScanning())
858 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
860 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
862 else if (m_vecItems->m_strPath.Equals("sources://video/"))
864 // get the usual shares
865 CGUIDialogContextMenu::GetContextButtons("video", item, buttons);
866 // add scan button somewhere here
867 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
868 if (pScanDlg && pScanDlg->IsScanning())
869 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning
870 if (!item->IsDVD() && item->m_strPath != "add" &&
871 (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
873 CVideoDatabase database;
875 ADDON::ScraperPtr info = database.GetScraperForPath(item->m_strPath);
877 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
879 if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
881 if (info && info->Content() != CONTENT_NONE)
882 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
884 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
888 if (info && (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning())))
889 buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
894 ADDON::ScraperPtr info;
895 VIDEO::SScanSettings settings;
896 GetScraperForItem(item.get(), info, settings);
898 if (info && info->Content() == CONTENT_TVSHOWS)
899 buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352);
900 else if (info && info->Content() == CONTENT_MUSICVIDEOS)
901 buttons.Add(CONTEXT_BUTTON_INFO,20393);
902 else if (!item->m_bIsFolder && !item->m_strPath.Left(19).Equals("newsmartplaylist://"))
903 buttons.Add(CONTEXT_BUTTON_INFO, 13346);
905 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strArtist.IsEmpty())
907 CMusicDatabase database;
909 if (database.GetArtistByName(item->GetVideoInfoTag()->m_strArtist) > -1)
910 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396);
912 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0)
914 CMusicDatabase database;
916 if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1)
917 buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397);
919 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 &&
920 item->GetVideoInfoTag()->m_strArtist.size() > 0 &&
921 item->GetVideoInfoTag()->m_strTitle.size() > 0)
923 CMusicDatabase database;
925 if (database.GetSongByArtistAndAlbumAndTitle(item->GetVideoInfoTag()->m_strArtist,
926 item->GetVideoInfoTag()->m_strAlbum,
927 item->GetVideoInfoTag()->m_strTitle) > -1)
929 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398);
932 if (!item->IsParentFolder())
934 // can we update the database?
935 if (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
937 if (node == NODE_TYPE_TITLE_TVSHOWS)
939 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
940 if (pScanDlg && pScanDlg->IsScanning())
941 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
943 buttons.Add(CONTEXT_BUTTON_UPDATE_TVSHOW, 13349);
945 if (!item->IsPlugin() && !item->IsLiveTV() && !item->IsAddonsPath() &&
946 item->m_strPath != "sources://video/" && item->m_strPath != "special://videoplaylists/")
948 if (item->m_bIsFolder)
950 // Have both options for folders since we don't know whether all childs are watched/unwatched
951 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
952 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
956 if (item->GetOverlayImage().Equals("OverlayWatched.png"))
957 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
959 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
962 if ((node == NODE_TYPE_TITLE_TVSHOWS) ||
963 (item->IsVideoDb() && item->HasVideoInfoTag() && !item->m_bIsFolder))
965 buttons.Add(CONTEXT_BUTTON_EDIT, 16105); //Edit Title
967 if (m_database.HasContent(VIDEODB_CONTENT_TVSHOWS) && item->HasVideoInfoTag() &&
968 !item->m_bIsFolder && item->GetVideoInfoTag()->m_iEpisode == -1 &&
969 item->GetVideoInfoTag()->m_strArtist.IsEmpty() && item->GetVideoInfoTag()->m_iDbId >= 0) // movie entry
971 if (m_database.IsLinkedToTvshow(item->GetVideoInfoTag()->m_iDbId))
972 buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE,20385);
973 buttons.Add(CONTEXT_BUTTON_LINK_MOVIE,20384);
976 if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
977 buttons.Add(CONTEXT_BUTTON_SET_SEASON_THUMB, 20371);
979 if (item->m_strPath.Left(14).Equals("videodb://1/7/") && item->m_strPath.size() > 14 && item->m_bIsFolder) // sets
981 buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
982 buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_THUMB, 20435);
983 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
986 if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder)
988 if (m_vecItems->m_strPath.Left(11).Equals("videodb://3")) // mvids
989 buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
991 buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
993 if (item->IsVideoDb() && item->HasVideoInfoTag() &&
994 (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS))
996 if (info && info->Content() == CONTENT_TVSHOWS)
998 if(item->GetVideoInfoTag()->m_iBookmarkId != -1 &&
999 item->GetVideoInfoTag()->m_iBookmarkId != 0)
1001 buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
1004 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
1007 // this should ideally be non-contextual (though we need some context for non-tv show node I guess)
1008 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1009 if (pScanDlg && pScanDlg->IsScanning())
1011 if (node != NODE_TYPE_TITLE_TVSHOWS)
1012 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
1015 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
1018 if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
1019 { // non-video db items, file operations are allowed
1020 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
1021 CUtil::SupportsFileOperations(item->m_strPath))
1023 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
1024 buttons.Add(CONTEXT_BUTTON_RENAME, 118);
1026 // add "Set/Change content" to folders
1027 if (item->m_bIsFolder && !item->IsPlayList() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
1029 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1030 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
1032 if (info && info->Content() != CONTENT_NONE)
1033 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
1035 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
1039 if (item->IsPlugin() || item->m_strPath.Left(9).Equals("script://") || m_vecItems->IsPlugin())
1040 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
1043 CGUIWindowVideoBase::GetNonContextButtons(itemNumber, buttons);
1046 bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
1049 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
1050 item = m_vecItems->Get(itemNumber);
1051 if (CGUIDialogContextMenu::OnContextButton("video", item, button))
1053 //TODO should we search DB for entries from plugins?
1054 if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin()
1055 && !item->IsLiveTV() &&!item->IsRSS())
1057 OnUnAssignContent(item->m_strPath,20375,20340,20341);
1059 Update(m_vecItems->m_strPath);
1064 case CONTEXT_BUTTON_EDIT:
1065 UpdateVideoTitle(item.get());
1066 CUtil::DeleteVideoDatabaseDirectoryCache();
1067 Update(m_vecItems->m_strPath);
1070 case CONTEXT_BUTTON_SET_SEASON_THUMB:
1071 case CONTEXT_BUTTON_SET_ACTOR_THUMB:
1072 case CONTEXT_BUTTON_SET_ARTIST_THUMB:
1073 case CONTEXT_BUTTON_SET_MOVIESET_THUMB:
1075 // Grab the thumbnails from the web
1077 CFileItemList items;
1078 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,"imdbthumbs",strPath);
1079 CFileItemPtr cacheItem(new CFileItem(strPath,true));
1080 CFileUtils::DeleteItem(cacheItem,true);
1081 XFILE::CDirectory::Create(strPath);
1082 CFileItemPtr noneitem(new CFileItem("thumb://None", false));
1083 CStdString cachedThumb = m_vecItems->Get(itemNumber)->GetCachedSeasonThumb();
1084 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1085 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedActorThumb();
1086 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1087 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedArtistThumb();
1088 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1089 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedVideoThumb();
1090 if (CFile::Exists(cachedThumb))
1092 CFileItemPtr item(new CFileItem("thumb://Current", false));
1093 item->SetThumbnailImage(cachedThumb);
1094 item->SetLabel(g_localizeStrings.Get(20016));
1097 noneitem->SetIconImage("DefaultFolder.png");
1098 noneitem->SetLabel(g_localizeStrings.Get(20018));
1100 vector<CStdString> thumbs;
1101 if (button != CONTEXT_BUTTON_SET_ARTIST_THUMB)
1104 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1105 m_database.GetTvShowInfo("",tag,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId);
1107 tag = *m_vecItems->Get(itemNumber)->GetVideoInfoTag();
1108 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1109 tag.m_strPictureURL.GetThumbURLs(thumbs, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iSeason);
1111 tag.m_strPictureURL.GetThumbURLs(thumbs);
1113 for (unsigned int i = 0; i < thumbs.size(); i++)
1115 CStdString strItemPath;
1116 strItemPath.Format("thumb://Remote%i",i);
1117 CFileItemPtr item(new CFileItem(strItemPath, false));
1118 item->SetThumbnailImage(thumbs[i]);
1119 item->SetIconImage("DefaultPicture.png");
1120 item->SetLabel(g_localizeStrings.Get(20015));
1123 // TODO: Do we need to clear the cached image?
1124 // CTextureCache::Get().ClearCachedImage(thumbs[i]);
1129 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1131 CStdString picturePath;
1133 CStdString strPath = m_vecItems->Get(itemNumber)->m_strPath;
1134 URIUtils::RemoveSlashAtEnd(strPath);
1136 int nPos=strPath.ReverseFind("/");
1139 // try to guess where the user should start
1140 // browsing for the artist thumb
1141 CMusicDatabase database;
1143 long idArtist=database.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
1144 database.GetArtistPath(idArtist, picturePath);
1147 CStdString strThumb;
1148 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1149 if (XFILE::CFile::Exists(strThumb))
1151 CFileItemPtr pItem(new CFileItem(strThumb,false));
1152 pItem->SetLabel(g_localizeStrings.Get(20017));
1153 pItem->SetThumbnailImage(strThumb);
1158 noneitem->SetIconImage("DefaultArtist.png");
1161 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1163 CStdString picturePath;
1164 CStdString strThumb;
1165 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1166 if (XFILE::CFile::Exists(strThumb))
1168 CFileItemPtr pItem(new CFileItem(strThumb,false));
1169 pItem->SetLabel(g_localizeStrings.Get(20017));
1170 pItem->SetThumbnailImage(strThumb);
1175 noneitem->SetIconImage("DefaultActor.png");
1178 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1179 noneitem->SetIconImage("DefaultVideo.png");
1182 items.Add(noneitem);
1184 VECSOURCES sources=g_settings.m_videoSources;
1185 g_mediaManager.GetLocalDrives(sources);
1187 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources,
1188 g_localizeStrings.Get(20019), result))
1190 return false; // user cancelled
1193 if (result == "thumb://Current")
1194 return false; // user chose the one they have
1196 // delete the thumbnail if that's what the user wants, else overwrite with the
1198 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1199 if (result.Left(14) == "thumb://Remote")
1201 int number = atoi(result.Mid(14));
1202 CFile::Cache(thumbs[number], cachedThumb);
1204 if (result == "thumb://None")
1205 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1207 CFile::Cache(result,cachedThumb);
1209 CUtil::DeleteVideoDatabaseDirectoryCache();
1210 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
1211 g_windowManager.SendMessage(msg);
1212 Update(m_vecItems->m_strPath);
1216 case CONTEXT_BUTTON_UPDATE_LIBRARY:
1221 case CONTEXT_BUTTON_UNLINK_MOVIE:
1223 OnLinkMovieToTvShow(itemNumber, true);
1224 Update(m_vecItems->m_strPath);
1227 case CONTEXT_BUTTON_LINK_MOVIE:
1229 OnLinkMovieToTvShow(itemNumber, false);
1232 case CONTEXT_BUTTON_GO_TO_ARTIST:
1235 CMusicDatabase database;
1237 strPath.Format("musicdb://2/%ld/",database.GetArtistByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist));
1238 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1241 case CONTEXT_BUTTON_GO_TO_ALBUM:
1244 CMusicDatabase database;
1246 strPath.Format("musicdb://3/%ld/",database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum));
1247 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1250 case CONTEXT_BUTTON_PLAY_OTHER:
1252 CMusicDatabase database;
1255 if (database.GetSongById(database.GetSongByArtistAndAlbumAndTitle(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum,
1256 m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle),
1259 g_application.getApplicationMessenger().PlayFile(song);
1264 case CONTEXT_BUTTON_UNLINK_BOOKMARK:
1267 m_database.DeleteBookMarkForEpisode(*m_vecItems->Get(itemNumber)->GetVideoInfoTag());
1269 CUtil::DeleteVideoDatabaseDirectoryCache();
1270 Update(m_vecItems->m_strPath);
1278 return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
1281 void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove)
1287 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1289 for (unsigned int i=0;i<ids.size();++i)
1292 m_database.GetTvShowInfo("",tag,ids[i]);
1293 CFileItemPtr show(new CFileItem(tag));
1299 m_database.GetTvShowsNav("videodb://2/2",list);
1301 // remove already linked shows
1303 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1305 for (int i=0;i<list.Size();)
1308 for (j=0;j<ids.size();++j)
1310 if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j])
1313 if (j == ids.size())
1319 int iSelectedLabel = 0;
1320 if (list.Size() > 1)
1322 list.Sort(g_guiSettings.GetBool("filelists.ignorethewhensorting") ? SORT_METHOD_LABEL_IGNORE_THE : SORT_METHOD_LABEL, SORT_ORDER_ASC);
1323 CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
1325 pDialog->SetItems(&list);
1326 pDialog->SetHeading(20356);
1328 iSelectedLabel = pDialog->GetSelectedLabel();
1330 if (iSelectedLabel > -1)
1332 m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,
1333 list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove);
1334 CUtil::DeleteVideoDatabaseDirectoryCache();
1338 bool CGUIWindowVideoNav::OnClick(int iItem)
1340 CFileItemPtr item = m_vecItems->Get(iItem);
1341 if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
1343 if (!DeleteItem(item.get(), true))
1347 m_vecItems->RemoveDiscCache(GetID());
1348 Update(m_vecItems->m_strPath);
1349 m_viewControl.SetSelectedItem(iItem);
1353 return CGUIWindowVideoBase::OnClick(iItem);
1356 CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
1358 if (dir.Equals("MovieGenres"))
1359 return "videodb://1/1/";
1360 else if (dir.Equals("MovieTitles"))
1361 return "videodb://1/2/";
1362 else if (dir.Equals("MovieYears"))
1363 return "videodb://1/3/";
1364 else if (dir.Equals("MovieActors"))
1365 return "videodb://1/4/";
1366 else if (dir.Equals("MovieDirectors"))
1367 return "videodb://1/5/";
1368 else if (dir.Equals("MovieStudios"))
1369 return "videodb://1/6/";
1370 else if (dir.Equals("MovieSets"))
1371 return "videodb://1/7/";
1372 else if (dir.Equals("MovieCountries"))
1373 return "videodb://1/8/";
1374 else if (dir.Equals("Movies"))
1375 return "videodb://1/";
1376 else if (dir.Equals("TvShowGenres"))
1377 return "videodb://2/1/";
1378 else if (dir.Equals("TvShowTitles"))
1379 return "videodb://2/2/";
1380 else if (dir.Equals("TvShowYears"))
1381 return "videodb://2/3/";
1382 else if (dir.Equals("TvShowActors"))
1383 return "videodb://2/4/";
1384 else if (dir.Equals("TvShowStudios"))
1385 return "videodb://2/5/";
1386 else if (dir.Equals("TvShows"))
1387 return "videodb://2/";
1388 else if (dir.Equals("MusicVideoGenres"))
1389 return "videodb://3/1/";
1390 else if (dir.Equals("MusicVideoTitles"))
1391 return "videodb://3/2/";
1392 else if (dir.Equals("MusicVideoYears"))
1393 return "videodb://3/3/";
1394 else if (dir.Equals("MusicVideoArtists"))
1395 return "videodb://3/4/";
1396 else if (dir.Equals("MusicVideoDirectors"))
1397 return "videodb://3/5/";
1398 else if (dir.Equals("MusicVideoStudios"))
1399 return "videodb://3/6/";
1400 else if (dir.Equals("MusicVideos"))
1401 return "videodb://3/";
1402 else if (dir.Equals("RecentlyAddedMovies"))
1403 return "videodb://4/";
1404 else if (dir.Equals("RecentlyAddedEpisodes"))
1405 return "videodb://5/";
1406 else if (dir.Equals("RecentlyAddedMusicVideos"))
1407 return "videodb://6/";
1408 else if (dir.Equals("Files"))
1409 return "sources://video/";
1410 return CGUIWindowVideoBase::GetStartFolder(dir);