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);
315 else if (type == VIDEODB_CONTENT_MOVIES)
317 m_castList->SetContent("movies");
319 // local trailers should always override non-local, so check
320 // for a local one if the registered trailer is online
321 if (m_movieItem->GetVideoInfoTag()->m_strTrailer.IsEmpty() ||
322 URIUtils::IsInternetStream(m_movieItem->GetVideoInfoTag()->m_strTrailer))
324 CStdString localTrailer = m_movieItem->FindTrailer();
325 if (!localTrailer.IsEmpty())
327 m_movieItem->GetVideoInfoTag()->m_strTrailer = localTrailer;
328 CVideoDatabase database;
331 database.SetDetail(m_movieItem->GetVideoInfoTag()->m_strTrailer,
332 m_movieItem->GetVideoInfoTag()->m_iDbId,
333 VIDEODB_ID_TRAILER, VIDEODB_CONTENT_MOVIES);
335 CUtil::DeleteVideoDatabaseDirectoryCache();
341 m_loader.LoadItem(m_movieItem.get());
344 void CGUIDialogVideoInfo::Update()
346 // setup plot text area
347 CStdString strTmp = m_movieItem->GetVideoInfoTag()->m_strPlot;
348 if (!(!m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty() && m_movieItem->GetVideoInfoTag()->m_iSeason == 0)) // dont apply to tvshows
349 if (m_movieItem->GetVideoInfoTag()->m_playCount == 0 && !g_guiSettings.GetBool("videolibrary.showunwatchedplots"))
350 strTmp = g_localizeStrings.Get(20370);
353 SetLabel(CONTROL_TEXTAREA, strTmp);
355 CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_LIST, 0, 0, m_castList);
358 if (GetControl(CONTROL_BTN_TRACKS)) // if no CONTROL_BTN_TRACKS found - allow skinner full visibility control over CONTROL_TEXTAREA and CONTROL_LIST
362 if (!m_movieItem->GetVideoInfoTag()->m_artist.empty())
364 SET_CONTROL_LABEL(CONTROL_BTN_TRACKS, 133);
368 SET_CONTROL_LABEL(CONTROL_BTN_TRACKS, 206);
371 SET_CONTROL_HIDDEN(CONTROL_LIST);
372 SET_CONTROL_VISIBLE(CONTROL_TEXTAREA);
376 SET_CONTROL_LABEL(CONTROL_BTN_TRACKS, 207);
378 SET_CONTROL_HIDDEN(CONTROL_TEXTAREA);
379 SET_CONTROL_VISIBLE(CONTROL_LIST);
383 // Check for resumability
384 if (m_movieItem->GetVideoInfoTag()->m_resumePoint.timeInSeconds > 0.0)
385 CONTROL_ENABLE(CONTROL_BTN_RESUME);
387 CONTROL_DISABLE(CONTROL_BTN_RESUME);
389 CONTROL_ENABLE(CONTROL_BTN_PLAY);
391 // update the thumbnail
392 const CGUIControl* pControl = GetControl(CONTROL_IMAGE);
395 CGUIImage* pImageControl = (CGUIImage*)pControl;
396 pImageControl->FreeResources();
397 pImageControl->SetFileName(m_movieItem->GetThumbnailImage());
399 // tell our GUI to completely reload all controls (as some of them
400 // are likely to have had this image in use so will need refreshing)
401 if (m_hasUpdatedThumb)
403 CGUIMessage reload(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
404 g_windowManager.SendMessage(reload);
408 bool CGUIDialogVideoInfo::NeedRefresh() const
413 bool CGUIDialogVideoInfo::RefreshAll() const
415 return m_bRefreshAll;
418 /// \brief Search the current directory for a string got from the virtual keyboard
419 void CGUIDialogVideoInfo::OnSearch(CStdString& strSearch)
423 m_dlgProgress->SetHeading(194);
424 m_dlgProgress->SetLine(0, strSearch);
425 m_dlgProgress->SetLine(1, "");
426 m_dlgProgress->SetLine(2, "");
427 m_dlgProgress->StartModal();
428 m_dlgProgress->Progress();
431 DoSearch(strSearch, items);
434 m_dlgProgress->Close();
438 CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
440 pDlgSelect->SetHeading(283);
442 for (int i = 0; i < (int)items.Size(); i++)
444 CFileItemPtr pItem = items[i];
445 pDlgSelect->Add(pItem->GetLabel());
448 pDlgSelect->DoModal();
450 int iItem = pDlgSelect->GetSelectedLabel();
454 CFileItem* pSelItem = new CFileItem(*items[iItem]);
456 OnSearchItemFound(pSelItem);
462 CGUIDialogOK::ShowAndGetInput(194, 284, 0, 0);
466 /// \brief Make the actual search for the OnSearch function.
467 /// \param strSearch The search string
468 /// \param items Items Found
469 void CGUIDialogVideoInfo::DoSearch(CStdString& strSearch, CFileItemList& items)
475 CFileItemList movies;
476 db.GetMoviesByActor(strSearch, movies);
477 for (int i = 0; i < movies.Size(); ++i)
479 CStdString label = movies[i]->GetVideoInfoTag()->m_strTitle;
480 if (movies[i]->GetVideoInfoTag()->m_iYear > 0)
481 label.AppendFormat(" (%i)", movies[i]->GetVideoInfoTag()->m_iYear);
482 movies[i]->SetLabel(label);
484 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20338) + "] ", items);
486 db.GetTvShowsByActor(strSearch, movies);
487 for (int i = 0; i < movies.Size(); ++i)
489 CStdString label = movies[i]->GetVideoInfoTag()->m_strShowTitle;
490 if (movies[i]->GetVideoInfoTag()->m_iYear > 0)
491 label.AppendFormat(" (%i)", movies[i]->GetVideoInfoTag()->m_iYear);
492 movies[i]->SetLabel(label);
494 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20364) + "] ", items);
496 db.GetEpisodesByActor(strSearch, movies);
497 for (int i = 0; i < movies.Size(); ++i)
499 CStdString label = movies[i]->GetVideoInfoTag()->m_strTitle + " (" + movies[i]->GetVideoInfoTag()->m_strShowTitle + ")";
500 movies[i]->SetLabel(label);
502 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20359) + "] ", items);
504 db.GetMusicVideosByArtist(strSearch, movies);
505 for (int i = 0; i < movies.Size(); ++i)
507 CStdString label = StringUtils::Join(movies[i]->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator) + " - " + movies[i]->GetVideoInfoTag()->m_strTitle;
508 if (movies[i]->GetVideoInfoTag()->m_iYear > 0)
509 label.AppendFormat(" (%i)", movies[i]->GetVideoInfoTag()->m_iYear);
510 movies[i]->SetLabel(label);
512 CGUIWindowVideoBase::AppendAndClearSearchItems(movies, "[" + g_localizeStrings.Get(20391) + "] ", items);
516 /// \brief React on the selected search item
517 /// \param pItem Search result item
518 void CGUIDialogVideoInfo::OnSearchItemFound(const CFileItem* pItem)
520 VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)pItem->GetVideoContentType();
526 CVideoInfoTag movieDetails;
527 if (type == VIDEODB_CONTENT_MOVIES)
528 db.GetMovieInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
529 if (type == VIDEODB_CONTENT_EPISODES)
530 db.GetEpisodeInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
531 if (type == VIDEODB_CONTENT_TVSHOWS)
532 db.GetTvShowInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
533 if (type == VIDEODB_CONTENT_MUSICVIDEOS)
534 db.GetMusicVideoInfo(pItem->GetPath(), movieDetails, pItem->GetVideoInfoTag()->m_iDbId);
537 CFileItem item(*pItem);
538 *item.GetVideoInfoTag() = movieDetails;
540 // refresh our window entirely
545 void CGUIDialogVideoInfo::ClearCastList()
547 CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_LIST);
552 void CGUIDialogVideoInfo::Play(bool resume)
554 if (!m_movieItem->GetVideoInfoTag()->m_strEpisodeGuide.IsEmpty())
557 strPath.Format("videodb://2/2/%i/",m_movieItem->GetVideoInfoTag()->m_iDbId);
559 g_windowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath);
563 CFileItem movie(*m_movieItem->GetVideoInfoTag());
564 if (m_movieItem->GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty())
565 movie.SetPath(m_movieItem->GetPath());
566 CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV);
572 movie.m_lStartOffset = STARTOFFSET_RESUME;
573 else if (!CGUIWindowVideoBase::ShowResumeMenu(movie))
575 // The Resume dialog was closed without any choice
579 pWindow->PlayMovie(&movie);
583 // Get Thumb from user choice.
588 // 4. No thumb (if no Local thumb is available)
589 void CGUIDialogVideoInfo::OnGetThumb()
594 if (CFile::Exists(m_movieItem->GetThumbnailImage()))
596 CFileItemPtr item(new CFileItem("thumb://Current", false));
597 item->SetThumbnailImage(m_movieItem->GetThumbnailImage());
598 item->SetLabel(g_localizeStrings.Get(20016));
602 // Grab the thumbnails from the web
603 vector<CStdString> thumbs;
604 m_movieItem->GetVideoInfoTag()->m_strPictureURL.GetThumbURLs(thumbs);
606 for (unsigned int i = 0; i < thumbs.size(); ++i)
608 CStdString strItemPath;
609 strItemPath.Format("thumb://Remote%i", i);
610 CFileItemPtr item(new CFileItem(strItemPath, false));
611 item->SetThumbnailImage(thumbs[i]);
612 item->SetIconImage("DefaultPicture.png");
613 item->SetLabel(g_localizeStrings.Get(20015));
615 // TODO: Do we need to clear the cached image?
616 // CTextureCache::Get().ClearCachedImage(thumb);
620 CStdString localThumb(m_movieItem->GetUserVideoThumb());
621 if (CFile::Exists(localThumb))
623 CFileItemPtr item(new CFileItem("thumb://Local", false));
624 item->SetThumbnailImage(localThumb);
625 item->SetLabel(g_localizeStrings.Get(20017));
629 { // no local thumb exists, so we are just using the IMDb thumb or cached thumb
630 // which is probably the IMDb thumb. These could be wrong, so allow the user
631 // to delete the incorrect thumb
632 CFileItemPtr item(new CFileItem("thumb://None", false));
633 item->SetIconImage("DefaultVideo.png");
634 item->SetLabel(g_localizeStrings.Get(20018));
639 VECSOURCES sources(g_settings.m_videoSources);
640 g_mediaManager.GetLocalDrives(sources);
641 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20019), result))
642 return; // user cancelled
644 if (result == "thumb://Current")
645 return; // user chose the one they have
648 if (result.Left(14) == "thumb://Remote")
650 int number = atoi(result.Mid(14));
651 newThumb = thumbs[number];
653 else if (result == "thumb://Local")
654 newThumb = localThumb;
655 else if (CFile::Exists(result))
658 newThumb = "-"; // force local thumbs to be ignored
660 // update thumb in the database
664 db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, "thumb", newThumb);
668 CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show
669 m_movieItem->SetThumbnailImage(newThumb);
670 if (m_movieItem->HasProperty("set_folder_thumb"))
671 { // have a folder thumb to set as well
672 VIDEO::CVideoInfoScanner::ApplyThumbToFolder(m_movieItem->GetProperty("set_folder_thumb").asString(), newThumb);
674 m_hasUpdatedThumb = true;
680 // Allow user to select a Fanart
681 void CGUIDialogVideoInfo::OnGetFanart()
685 CFileItem item(*m_movieItem->GetVideoInfoTag());
686 if (item.HasProperty("fanart_image"))
688 CFileItemPtr itemCurrent(new CFileItem("fanart://Current",false));
689 itemCurrent->SetThumbnailImage(item.GetProperty("fanart_image").asString());
690 itemCurrent->SetLabel(g_localizeStrings.Get(20440));
691 items.Add(itemCurrent);
694 // ensure the fanart is unpacked
695 m_movieItem->GetVideoInfoTag()->m_fanart.Unpack();
697 // Grab the thumbnails from the web
698 for (unsigned int i = 0; i < m_movieItem->GetVideoInfoTag()->m_fanart.GetNumFanarts(); i++)
700 CStdString strItemPath;
701 strItemPath.Format("fanart://Remote%i",i);
702 CFileItemPtr item(new CFileItem(strItemPath, false));
703 CStdString thumb = m_movieItem->GetVideoInfoTag()->m_fanart.GetPreviewURL(i);
704 item->SetThumbnailImage(CTextureCache::GetWrappedThumbURL(thumb));
705 item->SetIconImage("DefaultPicture.png");
706 item->SetLabel(g_localizeStrings.Get(20441));
708 // TODO: Do we need to clear the cached image?
709 // CTextureCache::Get().ClearCachedImage(thumb);
713 CStdString strLocal = item.GetLocalFanart();
714 if (!strLocal.IsEmpty())
716 CFileItemPtr itemLocal(new CFileItem("fanart://Local",false));
717 itemLocal->SetThumbnailImage(strLocal);
718 itemLocal->SetLabel(g_localizeStrings.Get(20438));
720 // TODO: Do we need to clear the cached image?
721 CTextureCache::Get().ClearCachedImage(strLocal);
722 items.Add(itemLocal);
726 CFileItemPtr itemNone(new CFileItem("fanart://None", false));
727 itemNone->SetIconImage("DefaultVideo.png");
728 itemNone->SetLabel(g_localizeStrings.Get(20439));
733 VECSOURCES sources(g_settings.m_videoSources);
734 g_mediaManager.GetLocalDrives(sources);
736 if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445) || result.Equals("fanart://Current"))
737 return; // user cancelled
739 if (result.Equals("fanart://Local"))
742 if (result.Left(15) == "fanart://Remote")
744 int iFanart = atoi(result.Mid(15).c_str());
745 // set new primary fanart, and update our database accordingly
746 m_movieItem->GetVideoInfoTag()->m_fanart.SetPrimaryFanart(iFanart);
750 db.UpdateFanart(*m_movieItem, (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType());
753 result = m_movieItem->GetVideoInfoTag()->m_fanart.GetImageURL();
755 else if (result.Equals("fanart://None") || !CFile::Exists(result))
758 // set the fanart image
759 if (flip && !result.IsEmpty())
760 result = CTextureCache::GetWrappedImageURL(result, "", "flipped");
764 db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, "fanart", result);
768 CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show
769 if (!result.IsEmpty())
770 m_movieItem->SetProperty("fanart_image", result);
772 m_movieItem->ClearProperty("fanart_image");
773 m_hasUpdatedThumb = true;
779 void CGUIDialogVideoInfo::PlayTrailer()
782 item.SetPath(m_movieItem->GetVideoInfoTag()->m_strTrailer);
783 *item.GetVideoInfoTag() = *m_movieItem->GetVideoInfoTag();
784 item.GetVideoInfoTag()->m_streamDetails.Reset();
785 item.GetVideoInfoTag()->m_strTitle.Format("%s (%s)",m_movieItem->GetVideoInfoTag()->m_strTitle.c_str(),g_localizeStrings.Get(20410));
786 item.SetThumbnailImage(m_movieItem->GetThumbnailImage());
787 item.GetVideoInfoTag()->m_iDbId = -1;
788 item.GetVideoInfoTag()->m_iFileId = -1;
793 if (item.IsPlayList())
794 g_application.getApplicationMessenger().MediaPlay(item);
796 g_application.getApplicationMessenger().PlayFile(item);
799 void CGUIDialogVideoInfo::SetLabel(int iControl, const CStdString &strLabel)
801 if (strLabel.IsEmpty())
803 SET_CONTROL_LABEL(iControl, 416); // "Not available"
807 SET_CONTROL_LABEL(iControl, strLabel);
811 const CStdString& CGUIDialogVideoInfo::GetThumbnail() const
813 return m_movieItem->GetThumbnailImage();