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 "GUIDialogVideoInfo.h"
23 #include "guilib/GUIWindow.h"
25 #include "guilib/GUIImage.h"
26 #include "utils/StringUtils.h"
27 #include "utils/URIUtils.h"
28 #include "video/windows/GUIWindowVideoNav.h"
29 #include "dialogs/GUIDialogFileBrowser.h"
30 #include "video/VideoInfoScanner.h"
31 #include "Application.h"
32 #include "video/VideoInfoTag.h"
33 #include "guilib/GUIWindowManager.h"
34 #include "dialogs/GUIDialogOK.h"
35 #include "dialogs/GUIDialogYesNo.h"
36 #include "dialogs/GUIDialogSelect.h"
37 #include "dialogs/GUIDialogProgress.h"
38 #include "filesystem/File.h"
40 #include "storage/MediaManager.h"
41 #include "utils/AsyncFileCopy.h"
42 #include "settings/Settings.h"
43 #include "settings/AdvancedSettings.h"
44 #include "settings/GUISettings.h"
45 #include "guilib/LocalizeStrings.h"
46 #include "GUIUserMessages.h"
47 #include "TextureCache.h"
48 #include "music/MusicDatabase.h"
51 using namespace XFILE;
53 #define CONTROL_IMAGE 3
54 #define CONTROL_TEXTAREA 4
55 #define CONTROL_BTN_TRACKS 5
56 #define CONTROL_BTN_REFRESH 6
57 #define CONTROL_BTN_PLAY 8
58 #define CONTROL_BTN_RESUME 9
59 #define CONTROL_BTN_GET_THUMB 10
60 #define CONTROL_BTN_PLAY_TRAILER 11
61 #define CONTROL_BTN_GET_FANART 12
62 #define CONTROL_BTN_DIRECTOR 13
64 #define CONTROL_LIST 50
66 CGUIDialogVideoInfo::CGUIDialogVideoInfo(void)
67 : CGUIDialog(WINDOW_DIALOG_VIDEO_INFO, "DialogVideoInfo.xml")
68 , m_movieItem(new CFileItem)
72 m_hasUpdatedThumb = false;
73 m_castList = new CFileItemList;
76 CGUIDialogVideoInfo::~CGUIDialogVideoInfo(void)
81 bool CGUIDialogVideoInfo::OnMessage(CGUIMessage& message)
83 switch ( message.GetMessage() )
85 case GUI_MSG_WINDOW_DEINIT:
91 case GUI_MSG_WINDOW_INIT:
93 m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
97 m_hasUpdatedThumb = false;
99 CGUIDialog::OnMessage(message);
100 m_bViewReview = true;
102 CVideoDatabase database;
103 ADDON::ScraperPtr scraper;
107 scraper = database.GetScraperForPath(m_movieItem->GetVideoInfoTag()->GetPath());
111 CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_REFRESH, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Left(2).Equals("xx") && scraper);
112 CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_THUMB, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin"));
114 VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType();
115 if (type == VIDEODB_CONTENT_TVSHOWS || type == VIDEODB_CONTENT_MOVIES)
116 CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_FANART, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin"));
118 CONTROL_DISABLE(CONTROL_BTN_GET_FANART);
126 case GUI_MSG_CLICKED:
128 int iControl = message.GetSenderId();
129 if (iControl == CONTROL_BTN_REFRESH)
131 if (m_movieItem->GetVideoInfoTag()->m_iSeason < 0 && !m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty()) // tv show
133 bool bCanceled=false;
134 if (CGUIDialogYesNo::ShowAndGetInput(20377,20378,-1,-1,bCanceled))
136 m_bRefreshAll = true;
140 db.SetPathHash(m_movieItem->GetVideoInfoTag()->m_strPath,"");
145 m_bRefreshAll = false;
154 else if (iControl == CONTROL_BTN_TRACKS)
156 m_bViewReview = !m_bViewReview;
159 else if (iControl == CONTROL_BTN_PLAY)
163 else if (iControl == CONTROL_BTN_RESUME)
167 else if (iControl == CONTROL_BTN_GET_THUMB)
171 else if (iControl == CONTROL_BTN_PLAY_TRAILER)
175 else if (iControl == CONTROL_BTN_GET_FANART)
179 else if (iControl == CONTROL_BTN_DIRECTOR)
181 CStdString strDirector = StringUtils::Join(m_movieItem->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
182 OnSearch(strDirector);
184 else if (iControl == CONTROL_LIST)
186 int iAction = message.GetParam1();
187 if (ACTION_SELECT_ITEM == iAction || ACTION_MOUSE_LEFT_CLICK == iAction)
189 CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl);
191 int iItem = msg.GetParam1();
192 if (iItem < 0 || iItem >= m_castList->Size())
194 CStdString strItem = m_castList->Get(iItem)->GetLabel();
196 strFind.Format(" %s ",g_localizeStrings.Get(20347));
197 int iPos = strItem.Find(strFind);
199 iPos = strItem.size();
200 CStdString tmp = strItem.Left(iPos);
206 case GUI_MSG_NOTIFY_ALL:
208 if (IsActive() && message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem())
210 CFileItemPtr item = boost::static_pointer_cast<CFileItem>(message.GetItem());
211 if (item && m_movieItem->GetPath().Equals(item->GetPath()))
212 { // Just copy over the stream details and the thumb if we don't already have one
213 if (!m_movieItem->HasThumbnail())
214 m_movieItem->SetThumbnailImage(item->GetThumbnailImage());
215 m_movieItem->GetVideoInfoTag()->m_streamDetails = item->GetVideoInfoTag()->m_streamDetails;
222 return CGUIDialog::OnMessage(message);
225 void CGUIDialogVideoInfo::SetMovie(const CFileItem *item)
227 *m_movieItem = *item;
228 // setup cast list + determine type. We need to do this here as it makes
229 // sure that content type (among other things) is set correctly for the
230 // old fixed id labels that we have floating around (they may be using
231 // content type to determine visibility, so we'll set the wrong label)
233 VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType();
234 if (type == VIDEODB_CONTENT_MUSICVIDEOS)
236 CMusicDatabase database;
238 const std::vector<std::string> &artists = m_movieItem->GetVideoInfoTag()->m_artist;
239 for (std::vector<std::string>::const_iterator it = artists.begin(); it != artists.end(); ++it)
241 int idArtist = database.GetArtistByName(*it);
242 CStdString thumb = database.GetArtForItem(idArtist, "artist", "thumb");
243 CFileItemPtr item(new CFileItem(*it));
245 item->SetThumbnailImage(thumb);
246 item->SetIconImage("DefaultArtist.png");
247 m_castList->Add(item);
249 m_castList->SetContent("musicvideos");
252 { // movie/show/episode
253 for (CVideoInfoTag::iCast it = m_movieItem->GetVideoInfoTag()->m_cast.begin(); it != m_movieItem->GetVideoInfoTag()->m_cast.end(); ++it)
255 CStdString character;
256 if (it->strRole.IsEmpty())
257 character = it->strName;
259 character.Format("%s %s %s", it->strName.c_str(), g_localizeStrings.Get(20347).c_str(), it->strRole.c_str());
260 CFileItemPtr item(new CFileItem(it->strName));
261 if (!it->thumb.IsEmpty())
262 item->SetThumbnailImage(it->thumb);
263 else if (g_guiSettings.GetBool("videolibrary.actorthumbs"))
264 { // backward compatibility
265 CStdString thumb = CScraperUrl::GetThumbURL(it->thumbUrl.GetFirstThumb());
266 if (!thumb.IsEmpty())
268 item->SetThumbnailImage(thumb);
269 CTextureCache::Get().BackgroundCacheImage(thumb);
272 item->SetIconImage("DefaultActor.png");
273 item->SetLabel(character);
274 m_castList->Add(item);
277 if (type == VIDEODB_CONTENT_TVSHOWS)
279 m_castList->SetContent("tvshows");
280 // special case stuff for shows (not currently retrieved from the library in filemode (ref: GetTvShowInfo vs GetTVShowsByWhere)
281 m_movieItem->m_dateTime = m_movieItem->GetVideoInfoTag()->m_premiered;
282 if(m_movieItem->GetVideoInfoTag()->m_iYear == 0 && m_movieItem->m_dateTime.IsValid())
283 m_movieItem->GetVideoInfoTag()->m_iYear = m_movieItem->m_dateTime.GetYear();
284 m_movieItem->SetProperty("totalepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode);
285 m_movieItem->SetProperty("numepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode); // info view has no concept of current watched/unwatched filter as we could come here from files view, but set for consistency
286 m_movieItem->SetProperty("watchedepisodes", m_movieItem->GetVideoInfoTag()->m_playCount);
287 m_movieItem->SetProperty("unwatchedepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode - m_movieItem->GetVideoInfoTag()->m_playCount);
288 m_movieItem->GetVideoInfoTag()->m_playCount = (m_movieItem->GetVideoInfoTag()->m_iEpisode == m_movieItem->GetVideoInfoTag()->m_playCount) ? 1 : 0;
290 else if (type == VIDEODB_CONTENT_EPISODES)
292 m_castList->SetContent("episodes");
293 // special case stuff for episodes (not currently retrieved from the library in filemode (ref: GetEpisodeInfo vs GetEpisodesByWhere)
294 m_movieItem->m_dateTime = m_movieItem->GetVideoInfoTag()->m_firstAired;
295 if(m_movieItem->GetVideoInfoTag()->m_iYear == 0 && m_movieItem->m_dateTime.IsValid())
296 m_movieItem->GetVideoInfoTag()->m_iYear = m_movieItem->m_dateTime.GetYear();
297 // retrieve the season thumb.
298 // TODO: should we use the thumbloader for this?
302 if (m_movieItem->GetVideoInfoTag()->m_iSeason > -1)
304 int seasonID = m_movieItem->GetVideoInfoTag()->m_iIdSeason;
306 seasonID = db.GetSeasonId(m_movieItem->GetVideoInfoTag()->m_iIdShow,
307 m_movieItem->GetVideoInfoTag()->m_iSeason);
308 string thumb = db.GetArtForItem(seasonID, "season", "thumb");
310 m_movieItem->SetProperty("seasonthumb", thumb);
312 if (m_movieItem->GetVideoInfoTag()->m_iIdShow > -1)
314 string thumb = db.GetArtForItem(m_movieItem->GetVideoInfoTag()->m_iIdShow, "tvshow", "thumb");
316 m_movieItem->SetProperty("tvshowthumb", thumb);
321 else if (type == VIDEODB_CONTENT_MOVIES)
323 m_castList->SetContent("movies");
325 // local trailers should always override non-local, so check
326 // for a local one if the registered trailer is online
327 if (m_movieItem->GetVideoInfoTag()->m_strTrailer.IsEmpty() ||
328 URIUtils::IsInternetStream(m_movieItem->GetVideoInfoTag()->m_strTrailer))
330 CStdString localTrailer = m_movieItem->FindTrailer();
331 if (!localTrailer.IsEmpty())
333 m_movieItem->GetVideoInfoTag()->m_strTrailer = localTrailer;
334 CVideoDatabase database;
337 database.SetDetail(m_movieItem->GetVideoInfoTag()->m_strTrailer,
338 m_movieItem->GetVideoInfoTag()->m_iDbId,
339 VIDEODB_ID_TRAILER, VIDEODB_CONTENT_MOVIES);
341 CUtil::DeleteVideoDatabaseDirectoryCache();
347 m_loader.LoadItem(m_movieItem.get());
350 void CGUIDialogVideoInfo::Update()
352 // setup plot text area
353 CStdString strTmp = m_movieItem->GetVideoInfoTag()->m_strPlot;
354 if (!(!m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty() && m_movieItem->GetVideoInfoTag()->m_iSeason == 0)) // dont apply to tvshows
355 if (m_movieItem->GetVideoInfoTag()->m_playCount == 0 && !g_guiSettings.GetBool("videolibrary.showunwatchedplots"))
356 strTmp = g_localizeStrings.Get(20370);
359 SetLabel(CONTROL_TEXTAREA, strTmp);
361 CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_LIST, 0, 0, m_castList);
364 if (GetControl(CONTROL_BTN_TRACKS)) // if no CONTROL_BTN_TRACKS found - allow skinner full visibility control over CONTROL_TEXTAREA and CONTROL_LIST
368 if (!m_movieItem->GetVideoInfoTag()->m_artist.empty())
370 SET_CONTROL_LABEL(CONTROL_BTN_TRACKS, 133);
374 SET_CONTROL_LABEL(CONTROL_BTN_TRACKS, 206);
377 SET_CONTROL_HIDDEN(CONTROL_LIST);
378 SET_CONTROL_VISIBLE(CONTROL_TEXTAREA);
382 SET_CONTROL_LABEL(CONTROL_BTN_TRACKS, 207);
384 SET_CONTROL_HIDDEN(CONTROL_TEXTAREA);
385 SET_CONTROL_VISIBLE(CONTROL_LIST);
389 // Check for resumability
390 if (m_movieItem->GetVideoInfoTag()->m_resumePoint.timeInSeconds > 0.0)
391 CONTROL_ENABLE(CONTROL_BTN_RESUME);
393 CONTROL_DISABLE(CONTROL_BTN_RESUME);
395 CONTROL_ENABLE(CONTROL_BTN_PLAY);
397 // update the thumbnail
398 const CGUIControl* pControl = GetControl(CONTROL_IMAGE);
401 CGUIImage* pImageControl = (CGUIImage*)pControl;
402 pImageControl->FreeResources();
403 pImageControl->SetFileName(m_movieItem->GetThumbnailImage());
405 // tell our GUI to completely reload all controls (as some of them
406 // are likely to have had this image in use so will need refreshing)
407 if (m_hasUpdatedThumb)
409 CGUIMessage reload(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
410 g_windowManager.SendMessage(reload);
414 bool CGUIDialogVideoInfo::NeedRefresh() const
419 bool CGUIDialogVideoInfo::RefreshAll() const
421 return m_bRefreshAll;
424 /// \brief Search the current directory for a string got from the virtual keyboard
425 void CGUIDialogVideoInfo::OnSearch(CStdString& strSearch)
429 m_dlgProgress->SetHeading(194);
430 m_dlgProgress->SetLine(0, strSearch);
431 m_dlgProgress->SetLine(1, "");
432 m_dlgProgress->SetLine(2, "");
433 m_dlgProgress->StartModal();
434 m_dlgProgress->Progress();
437 DoSearch(strSearch, items);
440 m_dlgProgress->Close();
444 CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
446 pDlgSelect->SetHeading(283);
448 for (int i = 0; i < (int)items.Size(); i++)
450 CFileItemPtr pItem = items[i];
451 pDlgSelect->Add(pItem->GetLabel());
454 pDlgSelect->DoModal();
456 int iItem = pDlgSelect->GetSelectedLabel();
460 CFileItem* pSelItem = new CFileItem(*items[iItem]);
462 OnSearchItemFound(pSelItem);
468 CGUIDialogOK::ShowAndGetInput(194, 284, 0, 0);
472 /// \brief Make the actual search for the OnSearch function.
473 /// \param strSearch The search string
474 /// \param items Items Found
475 void CGUIDialogVideoInfo::DoSearch(CStdString& strSearch, CFileItemList& items)
481 CFileItemList movies;
482 db.GetMoviesByActor(strSearch, movies);
483 for (int i = 0; i < movies.Size(); ++i)
485 CStdString label = movies[i]->GetVideoInfoTag()->m_strTitle;
486 if (movies[i]->GetVideoInfoTag()->m_iYear > 0)
487 label.AppendFormat(" (%i)", movies[i]->GetVideoInfoTag()->m_iYear);
488 movies[i]->SetLabel(label);
490 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20338) + "] ", items);
492 db.GetTvShowsByActor(strSearch, movies);
493 for (int i = 0; i < movies.Size(); ++i)
495 CStdString label = movies[i]->GetVideoInfoTag()->m_strShowTitle;
496 if (movies[i]->GetVideoInfoTag()->m_iYear > 0)
497 label.AppendFormat(" (%i)", movies[i]->GetVideoInfoTag()->m_iYear);
498 movies[i]->SetLabel(label);
500 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20364) + "] ", items);
502 db.GetEpisodesByActor(strSearch, movies);
503 for (int i = 0; i < movies.Size(); ++i)
505 CStdString label = movies[i]->GetVideoInfoTag()->m_strTitle + " (" + movies[i]->GetVideoInfoTag()->m_strShowTitle + ")";
506 movies[i]->SetLabel(label);
508 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20359) + "] ", items);
510 db.GetMusicVideosByArtist(strSearch, movies);
511 for (int i = 0; i < movies.Size(); ++i)
513 CStdString label = StringUtils::Join(movies[i]->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator) + " - " + movies[i]->GetVideoInfoTag()->m_strTitle;
514 if (movies[i]->GetVideoInfoTag()->m_iYear > 0)
515 label.AppendFormat(" (%i)", movies[i]->GetVideoInfoTag()->m_iYear);
516 movies[i]->SetLabel(label);
518 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20391) + "] ", items);
522 /// \brief React on the selected search item
523 /// \param pItem Search result item
524 void CGUIDialogVideoInfo::OnSearchItemFound(const CFileItem* pItem)
526 VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)pItem->GetVideoContentType();
532 CVideoInfoTag movieDetails;
533 if (type == VIDEODB_CONTENT_MOVIES)
534 db.GetMovieInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
535 if (type == VIDEODB_CONTENT_EPISODES)
536 db.GetEpisodeInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
537 if (type == VIDEODB_CONTENT_TVSHOWS)
538 db.GetTvShowInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
539 if (type == VIDEODB_CONTENT_MUSICVIDEOS)
540 db.GetMusicVideoInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
543 CFileItem item(*pItem);
544 *item.GetVideoInfoTag() = movieDetails;
546 // refresh our window entirely
551 void CGUIDialogVideoInfo::ClearCastList()
553 CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_LIST);
558 void CGUIDialogVideoInfo::Play(bool resume)
560 if (!m_movieItem->GetVideoInfoTag()->m_strEpisodeGuide.IsEmpty())
563 strPath.Format("videodb://2/2/%i/",m_movieItem->GetVideoInfoTag()->m_iDbId);
565 g_windowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath);
569 CFileItem movie(*m_movieItem->GetVideoInfoTag());
570 if (m_movieItem->GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty())
571 movie.SetPath(m_movieItem->GetPath());
572 CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV);
578 movie.m_lStartOffset = STARTOFFSET_RESUME;
579 else if (!CGUIWindowVideoBase::ShowResumeMenu(movie))
581 // The Resume dialog was closed without any choice
585 pWindow->PlayMovie(&movie);
589 // Get Thumb from user choice.
594 // 4. No thumb (if no Local thumb is available)
595 void CGUIDialogVideoInfo::OnGetThumb()
600 if (CFile::Exists(m_movieItem->GetThumbnailImage()))
602 CFileItemPtr item(new CFileItem("thumb://Current", false));
603 item->SetThumbnailImage(m_movieItem->GetThumbnailImage());
604 item->SetLabel(g_localizeStrings.Get(20016));
608 // Grab the thumbnails from the web
609 vector<CStdString> thumbs;
610 m_movieItem->GetVideoInfoTag()->m_strPictureURL.GetThumbURLs(thumbs);
612 for (unsigned int i = 0; i < thumbs.size(); ++i)
614 CStdString strItemPath;
615 strItemPath.Format("thumb://Remote%i", i);
616 CFileItemPtr item(new CFileItem(strItemPath, false));
617 item->SetThumbnailImage(thumbs[i]);
618 item->SetIconImage("DefaultPicture.png");
619 item->SetLabel(g_localizeStrings.Get(20015));
621 // TODO: Do we need to clear the cached image?
622 // CTextureCache::Get().ClearCachedImage(thumb);
626 CStdString localThumb(m_movieItem->GetUserVideoThumb());
627 if (CFile::Exists(localThumb))
629 CFileItemPtr item(new CFileItem("thumb://Local", false));
630 item->SetThumbnailImage(localThumb);
631 item->SetLabel(g_localizeStrings.Get(20017));
635 { // no local thumb exists, so we are just using the IMDb thumb or cached thumb
636 // which is probably the IMDb thumb. These could be wrong, so allow the user
637 // to delete the incorrect thumb
638 CFileItemPtr item(new CFileItem("thumb://None", false));
639 item->SetIconImage("DefaultVideo.png");
640 item->SetLabel(g_localizeStrings.Get(20018));
645 VECSOURCES sources(g_settings.m_videoSources);
646 g_mediaManager.GetLocalDrives(sources);
647 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20019), result))
648 return; // user cancelled
650 if (result == "thumb://Current")
651 return; // user chose the one they have
654 if (result.Left(14) == "thumb://Remote")
656 int number = atoi(result.Mid(14));
657 newThumb = thumbs[number];
659 else if (result == "thumb://Local")
660 newThumb = localThumb;
661 else if (CFile::Exists(result))
664 newThumb = "-"; // force local thumbs to be ignored
666 // update thumb in the database
670 db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, "thumb", newThumb);
674 CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show
675 m_movieItem->SetThumbnailImage(newThumb);
676 if (m_movieItem->HasProperty("set_folder_thumb"))
677 { // have a folder thumb to set as well
678 VIDEO::CVideoInfoScanner::ApplyThumbToFolder(m_movieItem->GetProperty("set_folder_thumb").asString(), newThumb);
680 m_hasUpdatedThumb = true;
686 // Allow user to select a Fanart
687 void CGUIDialogVideoInfo::OnGetFanart()
691 CFileItem item(*m_movieItem->GetVideoInfoTag());
692 if (item.HasProperty("fanart_image"))
694 CFileItemPtr itemCurrent(new CFileItem("fanart://Current",false));
695 itemCurrent->SetThumbnailImage(item.GetProperty("fanart_image").asString());
696 itemCurrent->SetLabel(g_localizeStrings.Get(20440));
697 items.Add(itemCurrent);
700 // ensure the fanart is unpacked
701 m_movieItem->GetVideoInfoTag()->m_fanart.Unpack();
703 // Grab the thumbnails from the web
704 for (unsigned int i = 0; i < m_movieItem->GetVideoInfoTag()->m_fanart.GetNumFanarts(); i++)
706 CStdString strItemPath;
707 strItemPath.Format("fanart://Remote%i",i);
708 CFileItemPtr item(new CFileItem(strItemPath, false));
709 CStdString thumb = m_movieItem->GetVideoInfoTag()->m_fanart.GetPreviewURL(i);
710 item->SetThumbnailImage(CTextureCache::GetWrappedThumbURL(thumb));
711 item->SetIconImage("DefaultPicture.png");
712 item->SetLabel(g_localizeStrings.Get(20441));
714 // TODO: Do we need to clear the cached image?
715 // CTextureCache::Get().ClearCachedImage(thumb);
719 CStdString strLocal = item.GetLocalFanart();
720 if (!strLocal.IsEmpty())
722 CFileItemPtr itemLocal(new CFileItem("fanart://Local",false));
723 itemLocal->SetThumbnailImage(strLocal);
724 itemLocal->SetLabel(g_localizeStrings.Get(20438));
726 // TODO: Do we need to clear the cached image?
727 CTextureCache::Get().ClearCachedImage(strLocal);
728 items.Add(itemLocal);
732 CFileItemPtr itemNone(new CFileItem("fanart://None", false));
733 itemNone->SetIconImage("DefaultVideo.png");
734 itemNone->SetLabel(g_localizeStrings.Get(20439));
739 VECSOURCES sources(g_settings.m_videoSources);
740 g_mediaManager.GetLocalDrives(sources);
742 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445) || result.Equals("fanart://Current"))
743 return; // user cancelled
745 if (result.Equals("fanart://Local"))
748 if (result.Left(15) == "fanart://Remote")
750 int iFanart = atoi(result.Mid(15).c_str());
751 // set new primary fanart, and update our database accordingly
752 m_movieItem->GetVideoInfoTag()->m_fanart.SetPrimaryFanart(iFanart);
756 db.UpdateFanart(*m_movieItem, (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType());
759 result = m_movieItem->GetVideoInfoTag()->m_fanart.GetImageURL();
761 else if (result.Equals("fanart://None") || !CFile::Exists(result))
764 // set the fanart image
765 if (flip && !result.IsEmpty())
766 result = CTextureCache::GetWrappedImageURL(result, "", "flipped");
770 db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, "fanart", result);
774 CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show
775 if (!result.IsEmpty())
776 m_movieItem->SetProperty("fanart_image", result);
778 m_movieItem->ClearProperty("fanart_image");
779 m_hasUpdatedThumb = true;
785 void CGUIDialogVideoInfo::PlayTrailer()
788 item.SetPath(m_movieItem->GetVideoInfoTag()->m_strTrailer);
789 *item.GetVideoInfoTag() = *m_movieItem->GetVideoInfoTag();
790 item.GetVideoInfoTag()->m_streamDetails.Reset();
791 item.GetVideoInfoTag()->m_strTitle.Format("%s (%s)",m_movieItem->GetVideoInfoTag()->m_strTitle.c_str(),g_localizeStrings.Get(20410));
792 item.SetThumbnailImage(m_movieItem->GetThumbnailImage());
793 item.GetVideoInfoTag()->m_iDbId = -1;
794 item.GetVideoInfoTag()->m_iFileId = -1;
799 if (item.IsPlayList())
800 g_application.getApplicationMessenger().MediaPlay(item);
802 g_application.getApplicationMessenger().PlayFile(item);
805 void CGUIDialogVideoInfo::SetLabel(int iControl, const CStdString &strLabel)
807 if (strLabel.IsEmpty())
809 SET_CONTROL_LABEL(iControl, 416); // "Not available"
813 SET_CONTROL_LABEL(iControl, strLabel);
817 const CStdString& CGUIDialogVideoInfo::GetThumbnail() const
819 return m_movieItem->GetThumbnailImage();