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 CFileItemList dbItems;
423 if (content.IsEmpty())
424 m_database.GetPlayCounts(items);
427 m_database.GetItemsForPath(content, items.m_strPath, dbItems);
428 dbItems.SetFastLookup(true);
430 for (int i = 0; i < items.Size(); i++)
432 CFileItemPtr pItem = items[i];
434 if (!content.IsEmpty())
435 match = dbItems.Get(pItem->m_strPath);
438 pItem->UpdateInfo(*match);
439 if (match->m_bIsFolder)
440 pItem->m_strPath = match->GetVideoInfoTag()->m_strPath;
442 pItem->m_strPath = match->GetVideoInfoTag()->m_strFileNameAndPath;
443 // if we switch from a file to a folder item it means we really shouldn't be sorting files and
444 // folders separately
445 if (pItem->m_bIsFolder != match->m_bIsFolder)
446 items.SetSortIgnoreFolders(true);
447 pItem->m_bIsFolder = match->m_bIsFolder;
450 { // set the watched overlay (note: items in a folder with content set that aren't in the db
451 // won't get picked up here - in the future all items will be returned)
452 // and clean the label
453 if (pItem->HasVideoInfoTag())
454 pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pItem->GetVideoInfoTag()->m_playCount > 0);
456 pItem->CleanString();
461 void CGUIWindowVideoNav::UpdateButtons()
463 CGUIWindowVideoBase::UpdateButtons();
465 // Update object count
466 int iItems = m_vecItems->Size();
469 // check for parent dir and "all" items
470 // should always be the first two items
471 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
473 CFileItemPtr pItem = m_vecItems->Get(i);
474 if (pItem->IsParentFolder()) iItems--;
475 if (pItem->m_strPath.Left(4).Equals("/-1/")) iItems--;
478 if (m_vecItems->Size() > 2 &&
479 m_vecItems->Get(m_vecItems->Size()-1)->m_strPath.Left(4).Equals("/-1/"))
483 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
484 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
486 // set the filter label
490 if (m_vecItems->m_strPath.Equals("special://videoplaylists/"))
491 strLabel = g_localizeStrings.Get(136);
493 else if (m_vecItems->IsPlayList())
495 // get playlist name from path
497 URIUtils::Split(m_vecItems->m_strPath, strDummy, strLabel);
499 else if (m_vecItems->m_strPath.Equals("sources://video/"))
500 strLabel = g_localizeStrings.Get(744);
501 // everything else is from a videodb:// path
502 else if (m_vecItems->IsVideoDb())
504 CVideoDatabaseDirectory dir;
505 dir.GetLabel(m_vecItems->m_strPath, strLabel);
508 strLabel = URIUtils::GetFileName(m_vecItems->m_strPath);
510 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
512 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
513 SET_CONTROL_LABEL(CONTROL_BTNSHOWMODE, g_localizeStrings.Get(16100 + watchMode));
515 SET_CONTROL_SELECTED(GetID(), CONTROL_BTNSHOWALL, watchMode != VIDEO_SHOW_ALL);
517 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
519 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNFLATTEN, g_settings.m_bMyVideoNavFlatten);
522 /// \brief Search for names, genres, artists, directors, and plots with search string \e strSearch in the
523 /// \brief video databases and return the found \e items
524 /// \param strSearch The search string
525 /// \param items Items Found
526 void CGUIWindowVideoNav::DoSearch(const CStdString& strSearch, CFileItemList& items)
528 CFileItemList tempItems;
529 CStdString strGenre = g_localizeStrings.Get(515); // Genre
530 CStdString strActor = g_localizeStrings.Get(20337); // Actor
531 CStdString strDirector = g_localizeStrings.Get(20339); // Director
532 CStdString strMovie = g_localizeStrings.Get(20338); // Movie
535 m_database.GetMoviesByName(strSearch, tempItems);
536 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20338) + "] ", items);
538 m_database.GetEpisodesByName(strSearch, tempItems);
539 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20359) + "] ", items);
541 m_database.GetTvShowsByName(strSearch, tempItems);
542 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20364) + "] ", items);
544 m_database.GetMusicVideosByName(strSearch, tempItems);
545 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20391) + "] ", items);
547 m_database.GetMusicVideosByAlbum(strSearch, tempItems);
548 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(558) + "] ", items);
550 // get matching genres
551 m_database.GetMovieGenresByName(strSearch, tempItems);
552 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20342) + "] ", items);
554 m_database.GetTvShowGenresByName(strSearch, tempItems);
555 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20343) + "] ", items);
557 m_database.GetMusicVideoGenresByName(strSearch, tempItems);
558 AppendAndClearSearchItems(tempItems, "[" + strGenre + " - " + g_localizeStrings.Get(20389) + "] ", items);
561 m_database.GetMovieActorsByName(strSearch, tempItems);
562 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20342) + "] ", items);
564 m_database.GetTvShowsActorsByName(strSearch, tempItems);
565 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20343) + "] ", items);
567 m_database.GetMusicVideoArtistsByName(strSearch, tempItems);
568 AppendAndClearSearchItems(tempItems, "[" + strActor + " - " + g_localizeStrings.Get(20389) + "] ", items);
571 m_database.GetMovieDirectorsByName(strSearch, tempItems);
572 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20342) + "] ", items);
574 m_database.GetTvShowsDirectorsByName(strSearch, tempItems);
575 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20343) + "] ", items);
577 m_database.GetMusicVideoDirectorsByName(strSearch, tempItems);
578 AppendAndClearSearchItems(tempItems, "[" + strDirector + " - " + g_localizeStrings.Get(20389) + "] ", items);
581 m_database.GetEpisodesByPlot(strSearch, tempItems);
582 AppendAndClearSearchItems(tempItems, "[" + g_localizeStrings.Get(20365) + "] ", items);
584 m_database.GetMoviesByPlot(strSearch, tempItems);
585 AppendAndClearSearchItems(tempItems, "[" + strMovie + " " + g_localizeStrings.Get(207) + "] ", items);
588 void CGUIWindowVideoNav::PlayItem(int iItem)
590 // unlike additemtoplaylist, we need to check the items here
591 // before calling it since the current playlist will be stopped
594 // root is not allowed
595 if (m_vecItems->IsVirtualDirectoryRoot())
598 CGUIWindowVideoBase::PlayItem(iItem);
601 void CGUIWindowVideoNav::OnInfo(CFileItem* pItem, ADDON::ScraperPtr& scraper)
603 m_database.Open(); // since we can be called from the music library without being inited
604 if (pItem->IsVideoDb())
605 scraper = m_database.GetScraperForPath(pItem->GetVideoInfoTag()->m_strPath);
608 CStdString strPath,strFile;
609 URIUtils::Split(pItem->m_strPath,strPath,strFile);
610 scraper = m_database.GetScraperForPath(strPath);
613 CGUIWindowVideoBase::OnInfo(pItem,scraper);
616 bool CGUIWindowVideoNav::CanDelete(const CStdString& strPath)
619 CVideoDatabaseDirectory::GetQueryParams(strPath,params);
621 if (params.GetMovieId() != -1 ||
622 params.GetEpisodeId() != -1 ||
623 params.GetMVideoId() != -1 ||
624 (params.GetTvShowId() != -1 && params.GetSeason() == -1
625 && !CVideoDatabaseDirectory::IsAllItem(strPath)))
631 void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
633 if (m_vecItems->IsParentFolder())
636 if (!m_vecItems->IsVideoDb())
638 if (!pItem->m_strPath.Equals("newsmartplaylist://video") &&
639 !pItem->m_strPath.Equals("special://videoplaylists/") &&
640 !pItem->m_strPath.Equals("sources://video/"))
641 CGUIWindowVideoBase::OnDeleteItem(pItem);
643 else if (pItem->m_strPath.Left(14).Equals("videodb://1/7/") &&
644 pItem->m_strPath.size() > 14 && pItem->m_bIsFolder)
646 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
647 pDialog->SetLine(0, g_localizeStrings.Get(432));
649 strLabel.Format(g_localizeStrings.Get(433),pItem->GetLabel());
650 pDialog->SetLine(1, strLabel);
651 pDialog->SetLine(2, "");;
653 if (pDialog->IsConfirmed())
656 CDirectory::GetDirectory(pItem->m_strPath,items,"",false,false,DIR_CACHE_ONCE,true,true);
657 for (int i=0;i<items.Size();++i)
658 OnDeleteItem(items[i]);
660 CVideoDatabaseDirectory dir;
662 dir.GetQueryParams(pItem->m_strPath,params);
663 m_database.DeleteSet(params.GetSetId());
668 if (!DeleteItem(pItem.get()))
671 CStdString strDeletePath;
672 if (pItem->m_bIsFolder)
673 strDeletePath=pItem->GetVideoInfoTag()->m_strPath;
675 strDeletePath=pItem->GetVideoInfoTag()->m_strFileNameAndPath;
677 if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
679 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
680 if (strDeletePath.Right(9).Equals("VIDEO_TS/"))
682 URIUtils::RemoveSlashAtEnd(strDeletePath);
683 URIUtils::GetDirectory(strDeletePath.Mid(0),strDeletePath);
686 if (URIUtils::HasSlashAtEnd(strDeletePath))
687 pItem->m_bIsFolder=true;
689 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
690 CUtil::SupportsFileOperations(strDeletePath))
692 pItem->m_strPath = strDeletePath;
693 CGUIWindowVideoBase::OnDeleteItem(pItem);
697 CUtil::DeleteVideoDatabaseDirectoryCache();
700 bool CGUIWindowVideoNav::DeleteItem(CFileItem* pItem, bool bUnavailable /* = false */)
702 if (!pItem->HasVideoInfoTag() || !CanDelete(pItem->m_strPath))
705 VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES;
706 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty())
707 iType = VIDEODB_CONTENT_TVSHOWS;
708 if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iSeason > -1 && !pItem->m_bIsFolder)
709 iType = VIDEODB_CONTENT_EPISODES;
710 if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strArtist.IsEmpty())
711 iType = VIDEODB_CONTENT_MUSICVIDEOS;
713 // dont allow update while scanning
714 CGUIDialogVideoScan* pDialogScan = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
715 if (pDialogScan && pDialogScan->IsScanning())
717 CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
722 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
725 if (iType == VIDEODB_CONTENT_MOVIES)
726 pDialog->SetHeading(432);
727 if (iType == VIDEODB_CONTENT_EPISODES)
728 pDialog->SetHeading(20362);
729 if (iType == VIDEODB_CONTENT_TVSHOWS)
730 pDialog->SetHeading(20363);
731 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
732 pDialog->SetHeading(20392);
736 pDialog->SetLine(0, g_localizeStrings.Get(662));
737 pDialog->SetLine(1, g_localizeStrings.Get(663));
738 pDialog->SetLine(2, "");;
744 strLine.Format(g_localizeStrings.Get(433),pItem->GetLabel());
745 pDialog->SetLine(0, strLine);
746 pDialog->SetLine(1, "");
747 pDialog->SetLine(2, "");;
751 if (!pDialog->IsConfirmed())
755 CVideoDatabase database;
758 database.GetFilePathById(pItem->GetVideoInfoTag()->m_iDbId, path, iType);
761 if (iType == VIDEODB_CONTENT_MOVIES)
762 database.DeleteMovie(path);
763 if (iType == VIDEODB_CONTENT_EPISODES)
764 database.DeleteEpisode(path, pItem->GetVideoInfoTag()->m_iDbId);
765 if (iType == VIDEODB_CONTENT_TVSHOWS)
766 database.DeleteTvShow(path);
767 if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
768 database.DeleteMusicVideo(path);
770 if (iType == VIDEODB_CONTENT_TVSHOWS)
771 database.SetPathHash(path,"");
774 CStdString strDirectory;
775 URIUtils::GetDirectory(path,strDirectory);
776 database.SetPathHash(strDirectory,"");
782 void CGUIWindowVideoNav::OnPrepareFileItems(CFileItemList &items)
784 CGUIWindowVideoBase::OnPrepareFileItems(items);
788 CVideoDatabaseDirectory dir;
789 dir.GetQueryParams(items.m_strPath,params);
790 if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
791 CGUIWindowMusicNav::SetupFanart(items);
793 NODE_TYPE node = dir.GetDirectoryChildType(items.m_strPath);
795 // now filter as necessary
796 bool filterWatched=false;
797 if (node == NODE_TYPE_EPISODES
798 || node == NODE_TYPE_SEASONS
799 || node == NODE_TYPE_TITLE_MOVIES
800 || node == NODE_TYPE_TITLE_TVSHOWS
801 || node == NODE_TYPE_TITLE_MUSICVIDEOS
802 || node == NODE_TYPE_RECENTLY_ADDED_EPISODES
803 || node == NODE_TYPE_RECENTLY_ADDED_MOVIES
804 || node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
805 filterWatched = true;
806 if (!items.IsVideoDb())
807 filterWatched = true;
808 if (items.IsSmartPlayList() && items.GetContent() == "tvshows")
809 node = NODE_TYPE_TITLE_TVSHOWS; // so that the check below works
811 int watchMode = g_settings.GetWatchMode(m_vecItems->GetContent());
813 for (int i = 0; i < items.Size(); i++)
815 CFileItemPtr item = items.Get(i);
816 if(item->HasVideoInfoTag() && (node == NODE_TYPE_TITLE_TVSHOWS || node == NODE_TYPE_SEASONS))
818 if (watchMode == VIDEO_SHOW_UNWATCHED)
819 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("unwatchedepisodes");
820 if (watchMode == VIDEO_SHOW_WATCHED)
821 item->GetVideoInfoTag()->m_iEpisode = item->GetPropertyInt("watchedepisodes");
822 item->SetProperty("numepisodes", item->GetVideoInfoTag()->m_iEpisode);
827 if((watchMode==VIDEO_SHOW_WATCHED && item->GetVideoInfoTag()->m_playCount== 0)
828 || (watchMode==VIDEO_SHOW_UNWATCHED && item->GetVideoInfoTag()->m_playCount > 0))
837 void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
840 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
841 item = m_vecItems->Get(itemNumber);
843 CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons);
845 if (item && item->GetPropertyBOOL("pluginreplacecontextitems"))
848 CVideoDatabaseDirectory dir;
849 NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->m_strPath);
853 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
854 if (pScanDlg && pScanDlg->IsScanning())
855 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
857 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
859 else if (m_vecItems->m_strPath.Equals("sources://video/"))
861 // get the usual shares
862 CGUIDialogContextMenu::GetContextButtons("video", item, buttons);
863 // add scan button somewhere here
864 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
865 if (pScanDlg && pScanDlg->IsScanning())
866 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning
867 if (!item->IsDVD() && item->m_strPath != "add" &&
868 (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
870 CVideoDatabase database;
872 ADDON::ScraperPtr info = database.GetScraperForPath(item->m_strPath);
874 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
876 if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
878 if (info && info->Content() != CONTENT_NONE)
879 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
881 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
885 if (info && (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning())))
886 buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
891 ADDON::ScraperPtr info;
892 VIDEO::SScanSettings settings;
893 GetScraperForItem(item.get(), info, settings);
895 if (info && info->Content() == CONTENT_TVSHOWS)
896 buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352);
897 else if (info && info->Content() == CONTENT_MUSICVIDEOS)
898 buttons.Add(CONTEXT_BUTTON_INFO,20393);
899 else if (!item->m_bIsFolder && !item->m_strPath.Left(19).Equals("newsmartplaylist://"))
900 buttons.Add(CONTEXT_BUTTON_INFO, 13346);
902 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strArtist.IsEmpty())
904 CMusicDatabase database;
906 if (database.GetArtistByName(item->GetVideoInfoTag()->m_strArtist) > -1)
907 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396);
909 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0)
911 CMusicDatabase database;
913 if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1)
914 buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397);
916 if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 &&
917 item->GetVideoInfoTag()->m_strArtist.size() > 0 &&
918 item->GetVideoInfoTag()->m_strTitle.size() > 0)
920 CMusicDatabase database;
922 if (database.GetSongByArtistAndAlbumAndTitle(item->GetVideoInfoTag()->m_strArtist,
923 item->GetVideoInfoTag()->m_strAlbum,
924 item->GetVideoInfoTag()->m_strTitle) > -1)
926 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398);
929 if (!item->IsParentFolder())
931 // can we update the database?
932 if (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
934 if (node == NODE_TYPE_TITLE_TVSHOWS)
936 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
937 if (pScanDlg && pScanDlg->IsScanning())
938 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
940 buttons.Add(CONTEXT_BUTTON_UPDATE_TVSHOW, 13349);
942 if (!item->IsPlugin() && !item->IsLiveTV() && !item->IsAddonsPath() &&
943 item->m_strPath != "sources://video/" && item->m_strPath != "special://videoplaylists/")
945 if (item->m_bIsFolder)
947 // Have both options for folders since we don't know whether all childs are watched/unwatched
948 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
949 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
953 if (item->GetOverlayImage().Equals("OverlayWatched.png"))
954 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
956 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
959 if ((node == NODE_TYPE_TITLE_TVSHOWS) ||
960 (item->IsVideoDb() && item->HasVideoInfoTag() && !item->m_bIsFolder))
962 buttons.Add(CONTEXT_BUTTON_EDIT, 16105); //Edit Title
964 if (m_database.HasContent(VIDEODB_CONTENT_TVSHOWS) && item->HasVideoInfoTag() &&
965 !item->m_bIsFolder && item->GetVideoInfoTag()->m_iEpisode == -1 &&
966 item->GetVideoInfoTag()->m_strArtist.IsEmpty() && item->GetVideoInfoTag()->m_iDbId >= 0) // movie entry
968 if (m_database.IsLinkedToTvshow(item->GetVideoInfoTag()->m_iDbId))
969 buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE,20385);
970 buttons.Add(CONTEXT_BUTTON_LINK_MOVIE,20384);
973 if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
974 buttons.Add(CONTEXT_BUTTON_SET_SEASON_THUMB, 20371);
976 if (item->m_strPath.Left(14).Equals("videodb://1/7/") && item->m_strPath.size() > 14 && item->m_bIsFolder) // sets
978 buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
979 buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_THUMB, 20435);
980 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
983 if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder)
985 if (m_vecItems->m_strPath.Left(11).Equals("videodb://3")) // mvids
986 buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
988 buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
990 if (item->IsVideoDb() && item->HasVideoInfoTag() &&
991 (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS))
993 if (info && info->Content() == CONTENT_TVSHOWS)
995 if(item->GetVideoInfoTag()->m_iBookmarkId != -1 &&
996 item->GetVideoInfoTag()->m_iBookmarkId != 0)
998 buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
1001 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
1004 // this should ideally be non-contextual (though we need some context for non-tv show node I guess)
1005 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1006 if (pScanDlg && pScanDlg->IsScanning())
1008 if (node != NODE_TYPE_TITLE_TVSHOWS)
1009 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
1012 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
1015 if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
1016 { // non-video db items, file operations are allowed
1017 if (g_guiSettings.GetBool("filelists.allowfiledeletion") &&
1018 CUtil::SupportsFileOperations(item->m_strPath))
1020 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
1021 buttons.Add(CONTEXT_BUTTON_RENAME, 118);
1023 // add "Set/Change content" to folders
1024 if (item->m_bIsFolder && !item->IsPlayList() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath())
1026 CGUIDialogVideoScan *pScanDlg = (CGUIDialogVideoScan *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
1027 if (!pScanDlg || (pScanDlg && !pScanDlg->IsScanning()))
1029 if (info && info->Content() != CONTENT_NONE)
1030 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
1032 buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
1036 if (item->IsPlugin() || item->m_strPath.Left(9).Equals("script://") || m_vecItems->IsPlugin())
1037 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
1040 CGUIWindowVideoBase::GetNonContextButtons(itemNumber, buttons);
1043 bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
1046 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
1047 item = m_vecItems->Get(itemNumber);
1048 if (CGUIDialogContextMenu::OnContextButton("video", item, button))
1050 //TODO should we search DB for entries from plugins?
1051 if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin()
1052 && !item->IsLiveTV() &&!item->IsRSS())
1054 OnUnAssignContent(item->m_strPath,20375,20340,20341);
1056 Update(m_vecItems->m_strPath);
1061 case CONTEXT_BUTTON_EDIT:
1062 UpdateVideoTitle(item.get());
1063 CUtil::DeleteVideoDatabaseDirectoryCache();
1064 Update(m_vecItems->m_strPath);
1067 case CONTEXT_BUTTON_SET_SEASON_THUMB:
1068 case CONTEXT_BUTTON_SET_ACTOR_THUMB:
1069 case CONTEXT_BUTTON_SET_ARTIST_THUMB:
1070 case CONTEXT_BUTTON_SET_MOVIESET_THUMB:
1072 // Grab the thumbnails from the web
1074 CFileItemList items;
1075 URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath,"imdbthumbs",strPath);
1076 CFileItemPtr cacheItem(new CFileItem(strPath,true));
1077 CFileUtils::DeleteItem(cacheItem,true);
1078 XFILE::CDirectory::Create(strPath);
1079 CFileItemPtr noneitem(new CFileItem("thumb://None", false));
1080 CStdString cachedThumb = m_vecItems->Get(itemNumber)->GetCachedSeasonThumb();
1081 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1082 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedActorThumb();
1083 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1084 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedArtistThumb();
1085 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1086 cachedThumb = m_vecItems->Get(itemNumber)->GetCachedVideoThumb();
1087 if (CFile::Exists(cachedThumb))
1089 CFileItemPtr item(new CFileItem("thumb://Current", false));
1090 item->SetThumbnailImage(cachedThumb);
1091 item->SetLabel(g_localizeStrings.Get(20016));
1094 noneitem->SetIconImage("DefaultFolder.png");
1095 noneitem->SetLabel(g_localizeStrings.Get(20018));
1097 vector<CStdString> thumbs;
1098 if (button != CONTEXT_BUTTON_SET_ARTIST_THUMB)
1101 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1102 m_database.GetTvShowInfo("",tag,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId);
1104 tag = *m_vecItems->Get(itemNumber)->GetVideoInfoTag();
1105 if (button == CONTEXT_BUTTON_SET_SEASON_THUMB)
1106 tag.m_strPictureURL.GetThumbURLs(thumbs, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iSeason);
1108 tag.m_strPictureURL.GetThumbURLs(thumbs);
1110 for (unsigned int i = 0; i < thumbs.size(); i++)
1112 CStdString strItemPath;
1113 strItemPath.Format("thumb://Remote%i",i);
1114 CFileItemPtr item(new CFileItem(strItemPath, false));
1115 item->SetThumbnailImage(thumbs[i]);
1116 item->SetIconImage("DefaultPicture.png");
1117 item->SetLabel(g_localizeStrings.Get(20015));
1120 // TODO: Do we need to clear the cached image?
1121 // CTextureCache::Get().ClearCachedImage(thumbs[i]);
1126 if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
1128 CStdString picturePath;
1130 CStdString strPath = m_vecItems->Get(itemNumber)->m_strPath;
1131 URIUtils::RemoveSlashAtEnd(strPath);
1133 int nPos=strPath.ReverseFind("/");
1136 // try to guess where the user should start
1137 // browsing for the artist thumb
1138 CMusicDatabase database;
1140 long idArtist=database.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
1141 database.GetArtistPath(idArtist, picturePath);
1144 CStdString strThumb;
1145 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1146 if (XFILE::CFile::Exists(strThumb))
1148 CFileItemPtr pItem(new CFileItem(strThumb,false));
1149 pItem->SetLabel(g_localizeStrings.Get(20017));
1150 pItem->SetThumbnailImage(strThumb);
1155 noneitem->SetIconImage("DefaultArtist.png");
1158 if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
1160 CStdString picturePath;
1161 CStdString strThumb;
1162 URIUtils::AddFileToFolder(picturePath,"folder.jpg",strThumb);
1163 if (XFILE::CFile::Exists(strThumb))
1165 CFileItemPtr pItem(new CFileItem(strThumb,false));
1166 pItem->SetLabel(g_localizeStrings.Get(20017));
1167 pItem->SetThumbnailImage(strThumb);
1172 noneitem->SetIconImage("DefaultActor.png");
1175 if (button == CONTEXT_BUTTON_SET_MOVIESET_THUMB)
1176 noneitem->SetIconImage("DefaultVideo.png");
1179 items.Add(noneitem);
1181 VECSOURCES sources=g_settings.m_videoSources;
1182 g_mediaManager.GetLocalDrives(sources);
1184 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources,
1185 g_localizeStrings.Get(20019), result))
1187 return false; // user cancelled
1190 if (result == "thumb://Current")
1191 return false; // user chose the one they have
1193 // delete the thumbnail if that's what the user wants, else overwrite with the
1195 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1196 if (result.Left(14) == "thumb://Remote")
1198 int number = atoi(result.Mid(14));
1199 CFile::Cache(thumbs[number], cachedThumb);
1201 if (result == "thumb://None")
1202 CTextureCache::Get().ClearCachedImage(cachedThumb, true);
1204 CFile::Cache(result,cachedThumb);
1206 CUtil::DeleteVideoDatabaseDirectoryCache();
1207 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
1208 g_windowManager.SendMessage(msg);
1209 Update(m_vecItems->m_strPath);
1213 case CONTEXT_BUTTON_UPDATE_LIBRARY:
1218 case CONTEXT_BUTTON_UNLINK_MOVIE:
1220 OnLinkMovieToTvShow(itemNumber, true);
1221 Update(m_vecItems->m_strPath);
1224 case CONTEXT_BUTTON_LINK_MOVIE:
1226 OnLinkMovieToTvShow(itemNumber, false);
1229 case CONTEXT_BUTTON_GO_TO_ARTIST:
1232 CMusicDatabase database;
1234 strPath.Format("musicdb://2/%ld/",database.GetArtistByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist));
1235 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1238 case CONTEXT_BUTTON_GO_TO_ALBUM:
1241 CMusicDatabase database;
1243 strPath.Format("musicdb://3/%ld/",database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum));
1244 g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
1247 case CONTEXT_BUTTON_PLAY_OTHER:
1249 CMusicDatabase database;
1252 if (database.GetSongById(database.GetSongByArtistAndAlbumAndTitle(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strArtist,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum,
1253 m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle),
1256 g_application.getApplicationMessenger().PlayFile(song);
1261 case CONTEXT_BUTTON_UNLINK_BOOKMARK:
1264 m_database.DeleteBookMarkForEpisode(*m_vecItems->Get(itemNumber)->GetVideoInfoTag());
1266 CUtil::DeleteVideoDatabaseDirectoryCache();
1267 Update(m_vecItems->m_strPath);
1275 return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
1278 void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove)
1284 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1286 for (unsigned int i=0;i<ids.size();++i)
1289 m_database.GetTvShowInfo("",tag,ids[i]);
1290 CFileItemPtr show(new CFileItem(tag));
1296 m_database.GetTvShowsNav("videodb://2/2",list);
1298 // remove already linked shows
1300 if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids))
1302 for (int i=0;i<list.Size();)
1305 for (j=0;j<ids.size();++j)
1307 if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j])
1310 if (j == ids.size())
1316 int iSelectedLabel = 0;
1317 if (list.Size() > 1)
1319 list.Sort(g_guiSettings.GetBool("filelists.ignorethewhensorting") ? SORT_METHOD_LABEL_IGNORE_THE : SORT_METHOD_LABEL, SORT_ORDER_ASC);
1320 CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
1322 pDialog->SetItems(&list);
1323 pDialog->SetHeading(20356);
1325 iSelectedLabel = pDialog->GetSelectedLabel();
1327 if (iSelectedLabel > -1)
1329 m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,
1330 list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove);
1331 CUtil::DeleteVideoDatabaseDirectoryCache();
1335 bool CGUIWindowVideoNav::OnClick(int iItem)
1337 CFileItemPtr item = m_vecItems->Get(iItem);
1338 if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
1340 if (!DeleteItem(item.get(), true))
1344 m_vecItems->RemoveDiscCache(GetID());
1345 Update(m_vecItems->m_strPath);
1346 m_viewControl.SetSelectedItem(iItem);
1350 return CGUIWindowVideoBase::OnClick(iItem);
1353 CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
1355 if (dir.Equals("MovieGenres"))
1356 return "videodb://1/1/";
1357 else if (dir.Equals("MovieTitles"))
1358 return "videodb://1/2/";
1359 else if (dir.Equals("MovieYears"))
1360 return "videodb://1/3/";
1361 else if (dir.Equals("MovieActors"))
1362 return "videodb://1/4/";
1363 else if (dir.Equals("MovieDirectors"))
1364 return "videodb://1/5/";
1365 else if (dir.Equals("MovieStudios"))
1366 return "videodb://1/6/";
1367 else if (dir.Equals("MovieSets"))
1368 return "videodb://1/7/";
1369 else if (dir.Equals("MovieCountries"))
1370 return "videodb://1/8/";
1371 else if (dir.Equals("Movies"))
1372 return "videodb://1/";
1373 else if (dir.Equals("TvShowGenres"))
1374 return "videodb://2/1/";
1375 else if (dir.Equals("TvShowTitles"))
1376 return "videodb://2/2/";
1377 else if (dir.Equals("TvShowYears"))
1378 return "videodb://2/3/";
1379 else if (dir.Equals("TvShowActors"))
1380 return "videodb://2/4/";
1381 else if (dir.Equals("TvShowStudios"))
1382 return "videodb://2/5/";
1383 else if (dir.Equals("TvShows"))
1384 return "videodb://2/";
1385 else if (dir.Equals("MusicVideoGenres"))
1386 return "videodb://3/1/";
1387 else if (dir.Equals("MusicVideoTitles"))
1388 return "videodb://3/2/";
1389 else if (dir.Equals("MusicVideoYears"))
1390 return "videodb://3/3/";
1391 else if (dir.Equals("MusicVideoArtists"))
1392 return "videodb://3/4/";
1393 else if (dir.Equals("MusicVideoDirectors"))
1394 return "videodb://3/5/";
1395 else if (dir.Equals("MusicVideoStudios"))
1396 return "videodb://3/6/";
1397 else if (dir.Equals("MusicVideos"))
1398 return "videodb://3/";
1399 else if (dir.Equals("RecentlyAddedMovies"))
1400 return "videodb://4/";
1401 else if (dir.Equals("RecentlyAddedEpisodes"))
1402 return "videodb://5/";
1403 else if (dir.Equals("RecentlyAddedMusicVideos"))
1404 return "videodb://6/";
1405 else if (dir.Equals("Files"))
1406 return "sources://video/";
1407 return CGUIWindowVideoBase::GetStartFolder(dir);