}
else
{
- CGUIWindowVideoNav::DeleteItem(item.get());
+ CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(item);
CUtil::DeleteVideoDatabaseDirectoryCache();
}
Refresh();
#include "video/VideoThumbLoader.h"
#include "filesystem/Directory.h"
#include "filesystem/VideoDatabaseDirectory.h"
+#include "filesystem/VideoDatabaseDirectory/QueryParams.h"
#ifdef HAS_UPNP
#include "network/upnp/UPnP.h"
#endif
+#include "utils/FileUtils.h"
using namespace std;
+using namespace XFILE::VIDEODATABASEDIRECTORY;
using namespace XFILE;
#define CONTROL_IMAGE 3
#define CONTROL_LIST 50
+// predicate used by sorting and set_difference
+bool compFileItemsByDbId(const CFileItemPtr& lhs, const CFileItemPtr& rhs)
+{
+ return lhs->HasVideoInfoTag() && rhs->HasVideoInfoTag() && lhs->GetVideoInfoTag()->m_iDbId < rhs->GetVideoInfoTag()->m_iDbId;
+}
+
CGUIDialogVideoInfo::CGUIDialogVideoInfo(void)
: CGUIDialog(WINDOW_DIALOG_VIDEO_INFO, "DialogVideoInfo.xml")
, m_movieItem(new CFileItem)
if (!database.Open())
return -1;
- VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)item->GetVideoContentType();
+ const std::string &type = item->GetVideoInfoTag()->m_type;
int dbId = item->GetVideoInfoTag()->m_iDbId;
CContextButtons buttons;
- buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
+ if (type == "movie" || type == "set" ||
+ type == "tvshow" || type == "episode" ||
+ type == "musicvideo")
+ buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
- if (type == VIDEODB_CONTENT_MOVIES || type == VIDEODB_CONTENT_TVSHOWS)
+ if (type == "movie" || type == "tvshow")
buttons.Add(CONTEXT_BUTTON_EDIT_SORTTITLE, 16107);
if (item->m_bIsFolder)
buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
}
- if (type == VIDEODB_CONTENT_MOVIES)
+ if (type == "movie")
{
// only show link/unlink if there are tvshows available
if (database.HasContent(VIDEODB_CONTENT_TVSHOWS))
buttons.Add(CONTEXT_BUTTON_SET_MOVIESET, 20465);
}
- if (type == VIDEODB_CONTENT_EPISODES &&
+ if (type == "episode" &&
item->GetVideoInfoTag()->m_iBookmarkId > 0)
buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
+ // movie sets
+ if (item->m_bIsFolder && type == "set")
+ {
+ buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_ART, 13511);
+ buttons.Add(CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS, 20465);
+ }
+
+ // tags
+ if (item->m_bIsFolder && type == "tag")
+ {
+ CVideoDbUrl videoUrl;
+ if (videoUrl.FromString(item->GetPath()))
+ {
+ const std::string &mediaType = videoUrl.GetItemType();
+
+ buttons.Add(CONTEXT_BUTTON_TAGS_ADD_ITEMS, StringUtils::Format(g_localizeStrings.Get(20460), GetLocalizedVideoType(mediaType).c_str()));
+ buttons.Add(CONTEXT_BUTTON_TAGS_REMOVE_ITEMS, StringUtils::Format(g_localizeStrings.Get(20461), GetLocalizedVideoType(mediaType).c_str()));
+ }
+ }
+
+ buttons.Add(CONTEXT_BUTTON_DELETE, 646);
+
bool result = false;
int button = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
if (button >= 0)
result = true;
break;
+ case CONTEXT_BUTTON_DELETE:
+ result = DeleteVideoItem(item);
+ break;
+
+ case CONTEXT_BUTTON_SET_MOVIESET_ART:
+ result = ManageVideoItemArtwork(item, "set");
+ break;
+
+ case CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS:
+ result = ManageMovieSets(item);
+ break;
+
+ case CONTEXT_BUTTON_TAGS_ADD_ITEMS:
+ result = AddItemsToTag(item);
+ break;
+
+ case CONTEXT_BUTTON_TAGS_REMOVE_ITEMS:
+ result = RemoveItemsFromTag(item);
+ break;
+
default:
result = false;
break;
//Add change a title's name
bool CGUIDialogVideoInfo::UpdateVideoItemTitle(const CFileItemPtr &pItem)
{
+ if (pItem == NULL || !pItem->HasVideoInfoTag())
+ return false;
+
// dont allow update while scanning
if (g_application.IsVideoScanning())
{
bool CGUIDialogVideoInfo::MarkWatched(const CFileItemPtr &item, bool bMark)
{
- if (!CProfilesManager::Get().GetCurrentProfile().canWriteDatabases())
+ if (item == NULL || !CProfilesManager::Get().GetCurrentProfile().canWriteDatabases())
return false;
// dont allow update while scanning
return true;
}
+bool CGUIDialogVideoInfo::CanDeleteVideoItem(const CFileItemPtr &item)
+{
+ if (item == NULL || !item->HasVideoInfoTag())
+ return false;
+
+ CQueryParams params;
+ CVideoDatabaseDirectory::GetQueryParams(item->GetPath(), params);
+
+ return params.GetMovieId() != -1 ||
+ params.GetEpisodeId() != -1 ||
+ params.GetMVideoId() != -1 ||
+ (params.GetTvShowId() != -1 && params.GetSeason() <= -1 &&
+ !CVideoDatabaseDirectory::IsAllItem(item->GetPath()));
+}
+
+bool CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(const CFileItemPtr &item, bool unavailable /* = false */)
+{
+ if (item == NULL || !item->HasVideoInfoTag() ||
+ !CanDeleteVideoItem(item))
+ return false;
+
+ // dont allow update while scanning
+ if (g_application.IsVideoScanning())
+ {
+ CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
+ return false;
+ }
+
+ CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
+ if (pDialog == NULL)
+ return false;
+
+ int heading = -1;
+ VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)item->GetVideoContentType();
+ switch (type)
+ {
+ case VIDEODB_CONTENT_MOVIES:
+ heading = 432;
+ break;
+ case VIDEODB_CONTENT_EPISODES:
+ heading = 20362;
+ break;
+ case VIDEODB_CONTENT_TVSHOWS:
+ heading = 20363;
+ break;
+ case VIDEODB_CONTENT_MUSICVIDEOS:
+ heading = 20392;
+ break;
+
+ default:
+ return false;
+ }
+
+ pDialog->SetHeading(heading);
+
+ if (unavailable)
+ {
+ pDialog->SetLine(0, g_localizeStrings.Get(662));
+ pDialog->SetLine(1, g_localizeStrings.Get(663));
+ }
+ else
+ {
+ pDialog->SetLine(0, StringUtils::Format(g_localizeStrings.Get(433), item->GetLabel().c_str()));
+ pDialog->SetLine(1, "");
+ }
+ pDialog->SetLine(2, "");
+ pDialog->DoModal();
+
+ if (!pDialog->IsConfirmed())
+ return false;
+
+ CStdString path;
+ CVideoDatabase database;
+ database.Open();
+
+ database.GetFilePathById(item->GetVideoInfoTag()->m_iDbId, path, type);
+ if (path.empty())
+ return false;
+
+ switch (type)
+ {
+ case VIDEODB_CONTENT_MOVIES:
+ database.DeleteMovie(path);
+ break;
+ case VIDEODB_CONTENT_EPISODES:
+ database.DeleteEpisode(path, item->GetVideoInfoTag()->m_iDbId);
+ break;
+ case VIDEODB_CONTENT_TVSHOWS:
+ database.DeleteTvShow(path);
+ break;
+ case VIDEODB_CONTENT_MUSICVIDEOS:
+ database.DeleteMusicVideo(path);
+ break;
+
+ default:
+ return false;
+ }
+
+ if (type == VIDEODB_CONTENT_TVSHOWS)
+ database.SetPathHash(path,"");
+ else
+ database.SetPathHash(URIUtils::GetDirectory(path), "");
+
+ return true;
+}
+
+bool CGUIDialogVideoInfo::DeleteVideoItem(const CFileItemPtr &item, bool unavailable /* = false */)
+{
+ if (item == NULL)
+ return false;
+
+ // delete the video item from the database
+ if (!DeleteVideoItemFromDatabase(item, unavailable))
+ return false;
+
+ bool result = true;
+ // check if the user is allowed to delete the actual file as well
+ if ((CProfilesManager::Get().GetCurrentProfile().getLockMode() == LOCK_MODE_EVERYONE ||
+ !CProfilesManager::Get().GetCurrentProfile().filesLocked() ||
+ g_passwordManager.IsMasterLockUnlocked(true)) &&
+ CSettings::Get().GetBool("filelists.allowfiledeletion"))
+ {
+ CStdString strDeletePath = item->GetVideoInfoTag()->GetPath();
+
+ if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
+ {
+ strDeletePath = URIUtils::GetDirectory(strDeletePath);
+ if (StringUtils::EndsWithNoCase(strDeletePath, "video_ts/"))
+ {
+ URIUtils::RemoveSlashAtEnd(strDeletePath);
+ strDeletePath = URIUtils::GetDirectory(strDeletePath);
+ }
+ }
+ if (URIUtils::HasSlashAtEnd(strDeletePath))
+ item->m_bIsFolder = true;
+
+ // check if the file/directory can be deleted
+ if (CUtil::SupportsWriteFileOperations(strDeletePath))
+ {
+ item->SetPath(strDeletePath);
+
+ // HACK: stacked files need to be treated as folders in order to be deleted
+ if (item->IsStack())
+ item->m_bIsFolder = true;
+ result = CFileUtils::DeleteItem(item);
+ }
+ }
+
+ CUtil::DeleteVideoDatabaseDirectoryCache();
+
+ return result;
+}
+
+bool CGUIDialogVideoInfo::ManageMovieSets(const CFileItemPtr &item)
+{
+ if (item == NULL)
+ return false;
+
+ CFileItemList originalItems;
+ CFileItemList selectedItems;
+
+ if (!GetMoviesForSet(item.get(), originalItems, selectedItems) ||
+ selectedItems.Size() == 0) // need at least one item selected
+ return false;
+
+ VECFILEITEMS original = originalItems.GetList();
+ std::sort(original.begin(), original.end(), compFileItemsByDbId);
+ VECFILEITEMS selected = selectedItems.GetList();
+ std::sort(selected.begin(), selected.end(), compFileItemsByDbId);
+
+ bool refreshNeeded = false;
+ // update the "added" items
+ VECFILEITEMS addedItems;
+ set_difference(selected.begin(),selected.end(), original.begin(),original.end(), std::back_inserter(addedItems), compFileItemsByDbId);
+ for (VECFILEITEMS::const_iterator it = addedItems.begin(); it != addedItems.end(); ++it)
+ {
+ if (SetMovieSet(it->get(), item.get()))
+ refreshNeeded = true;
+ }
+
+ // update the "deleted" items
+ CFileItemPtr clearItem(new CFileItem());
+ clearItem->GetVideoInfoTag()->m_iDbId = -1; // -1 will be used to clear set
+ VECFILEITEMS deletedItems;
+ set_difference(original.begin(),original.end(), selected.begin(),selected.end(), std::back_inserter(deletedItems), compFileItemsByDbId);
+ for (VECFILEITEMS::iterator it = deletedItems.begin(); it != deletedItems.end(); ++it)
+ {
+ if (SetMovieSet(it->get(), clearItem.get()))
+ refreshNeeded = true;
+ }
+
+ return refreshNeeded;
+}
+
bool CGUIDialogVideoInfo::GetMoviesForSet(const CFileItem *setItem, CFileItemList &originalMovies, CFileItemList &selectedMovies)
{
+ if (setItem == NULL || !setItem->HasVideoInfoTag())
+ return false;
+
CVideoDatabase videodb;
if (!videodb.Open())
return false;
bool CGUIDialogVideoInfo::GetSetForMovie(const CFileItem *movieItem, CFileItemPtr &selectedSet)
{
+ if (movieItem == NULL || !movieItem->HasVideoInfoTag() ||
+ selectedSet == NULL)
+ return false;
+
CVideoDatabase videodb;
if (!videodb.Open())
return false;
bool CGUIDialogVideoInfo::SetMovieSet(const CFileItem *movieItem, const CFileItem *selectedSet)
{
+ if (movieItem == NULL || !movieItem->HasVideoInfoTag() ||
+ selectedSet == NULL || !selectedSet->HasVideoInfoTag())
+ return false;
+
CVideoDatabase videodb;
if (!videodb.Open())
return false;
return true;
}
+bool CGUIDialogVideoInfo::GetItemsForTag(const CStdString &strHeading, const std::string &type, CFileItemList &items, int idTag /* = -1 */, bool showAll /* = true */)
+{
+ CVideoDatabase videodb;
+ if (!videodb.Open())
+ return false;
+
+ MediaType mediaType = MediaTypeNone;
+ std::string baseDir = "videodb://";
+ std::string idColumn;
+ if (type.compare("movie") == 0)
+ {
+ mediaType = MediaTypeMovie;
+ baseDir += "movies";
+ idColumn = "idMovie";
+ }
+ else if (type.compare("tvshow") == 0)
+ {
+ mediaType = MediaTypeTvShow;
+ baseDir += "tvshows";
+ idColumn = "idShow";
+ }
+ else if (type.compare("musicvideo") == 0)
+ {
+ mediaType = MediaTypeMusicVideo;
+ baseDir += "musicvideos";
+ idColumn = "idMVideo";
+ }
+
+ baseDir += "/titles/";
+ CVideoDbUrl videoUrl;
+ if (!videoUrl.FromString(baseDir))
+ return false;
+
+ CVideoDatabase::Filter filter;
+ if (idTag > 0)
+ {
+ if (!showAll)
+ videoUrl.AddOption("tagid", idTag);
+ else
+ filter.where = videodb.PrepareSQL("%sview.%s NOT IN (SELECT taglinks.idMedia FROM taglinks WHERE taglinks.idTag = %d AND taglinks.media_type = '%s')", type.c_str(), idColumn.c_str(), idTag, type.c_str());
+ }
+
+ CFileItemList listItems;
+ if (!videodb.GetSortedVideos(mediaType, videoUrl.ToString(), SortDescription(), listItems, filter) || listItems.Size() <= 0)
+ return false;
+
+ CGUIDialogSelect *dialog = (CGUIDialogSelect *)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
+ if (dialog == NULL)
+ return false;
+
+ listItems.Sort(SortByLabel, SortOrderAscending, SortAttributeIgnoreArticle);
+
+ dialog->Reset();
+ dialog->SetMultiSelection(true);
+ dialog->SetHeading(strHeading);
+ dialog->SetItems(&listItems);
+ dialog->EnableButton(true, 186);
+ dialog->DoModal();
+
+ items.Copy(dialog->GetSelectedItems());
+ return items.Size() > 0;
+}
+
+bool CGUIDialogVideoInfo::AddItemsToTag(const CFileItemPtr &tagItem)
+{
+ if (tagItem == NULL || !tagItem->HasVideoInfoTag())
+ return false;
+
+ CVideoDbUrl videoUrl;
+ if (!videoUrl.FromString(tagItem->GetPath()))
+ return false;
+
+ CVideoDatabase videodb;
+ if (!videodb.Open())
+ return true;
+
+ std::string mediaType = videoUrl.GetItemType();
+ mediaType = mediaType.substr(0, mediaType.length() - 1);
+
+ CFileItemList items;
+ std::string localizedType = GetLocalizedVideoType(mediaType);
+ std::string strLabel = StringUtils::Format(g_localizeStrings.Get(20464), localizedType.c_str());
+ if (!GetItemsForTag(strLabel, mediaType, items, tagItem->GetVideoInfoTag()->m_iDbId))
+ return true;
+
+ for (int index = 0; index < items.Size(); index++)
+ {
+ if (!items[index]->HasVideoInfoTag() || items[index]->GetVideoInfoTag()->m_iDbId <= 0)
+ continue;
+
+ videodb.AddTagToItem(items[index]->GetVideoInfoTag()->m_iDbId, tagItem->GetVideoInfoTag()->m_iDbId, mediaType);
+ }
+
+ return true;
+}
+
+bool CGUIDialogVideoInfo::RemoveItemsFromTag(const CFileItemPtr &tagItem)
+{
+ if (tagItem == NULL || !tagItem->HasVideoInfoTag())
+ return false;
+
+ CVideoDbUrl videoUrl;
+ if (!videoUrl.FromString(tagItem->GetPath()))
+ return false;
+
+ CVideoDatabase videodb;
+ if (!videodb.Open())
+ return true;
+
+ std::string mediaType = videoUrl.GetItemType();
+ mediaType = mediaType.substr(0, mediaType.length() - 1);
+
+ CFileItemList items;
+ std::string localizedType = GetLocalizedVideoType(mediaType);
+ std::string strLabel = StringUtils::Format(g_localizeStrings.Get(20464), localizedType.c_str());
+ if (!GetItemsForTag(strLabel, mediaType, items, tagItem->GetVideoInfoTag()->m_iDbId, false))
+ return true;
+
+ for (int index = 0; index < items.Size(); index++)
+ {
+ if (!items[index]->HasVideoInfoTag() || items[index]->GetVideoInfoTag()->m_iDbId <= 0)
+ continue;
+
+ videodb.RemoveTagFromItem(items[index]->GetVideoInfoTag()->m_iDbId, tagItem->GetVideoInfoTag()->m_iDbId, mediaType);
+ }
+
+ return true;
+}
+
+bool CGUIDialogVideoInfo::ManageVideoItemArtwork(const CFileItemPtr &item, const std::string &type)
+{
+ if (item == NULL || !item->HasVideoInfoTag() || type.empty())
+ return false;
+
+ CVideoDatabase videodb;
+ if (!videodb.Open())
+ return true;
+
+ // Grab the thumbnails from the web
+ CFileItemList items;
+ CFileItemPtr noneitem(new CFileItem("thumb://None", false));
+ std::string currentThumb;
+ int idArtist = -1;
+ CStdString artistPath;
+ string artType = "thumb";
+ if (type == "artist")
+ {
+ CMusicDatabase musicdb;
+ if (musicdb.Open())
+ {
+ idArtist = musicdb.GetArtistByName(item->GetLabel());
+ if (idArtist >= 0 && musicdb.GetArtistPath(idArtist, artistPath))
+ {
+ currentThumb = musicdb.GetArtForItem(idArtist, "artist", "thumb");
+ if (currentThumb.empty())
+ currentThumb = videodb.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artType);
+ }
+ }
+ }
+ else if (type == "actor")
+ currentThumb = videodb.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artType);
+ else
+ { // SEASON, SET
+ map<string, string> currentArt;
+ artType = ChooseArtType(*item, currentArt);
+ if (artType.empty())
+ return false;
+
+ if (artType == "fanart")
+ return OnGetFanart(item);
+
+ if (currentArt.find(artType) != currentArt.end())
+ currentThumb = currentArt[artType];
+ else if ((artType == "poster" || artType == "banner") && currentArt.find("thumb") != currentArt.end())
+ currentThumb = currentArt["thumb"];
+ }
+
+ if (!currentThumb.empty())
+ {
+ CFileItemPtr item(new CFileItem("thumb://Current", false));
+ item->SetArt("thumb", currentThumb);
+ item->SetLabel(g_localizeStrings.Get(13512));
+ items.Add(item);
+ }
+ noneitem->SetIconImage("DefaultFolder.png");
+ noneitem->SetLabel(g_localizeStrings.Get(13515));
+
+ bool local = false;
+ vector<CStdString> thumbs;
+ if (type != "artist")
+ {
+ CVideoInfoTag tag;
+ if (type == "season")
+ videodb.GetTvShowInfo("", tag, item->GetVideoInfoTag()->m_iIdShow);
+ else
+ tag = *item->GetVideoInfoTag();
+
+ tag.m_strPictureURL.GetThumbURLs(thumbs, artType, type == "season" ? item->GetVideoInfoTag()->m_iSeason : -1);
+
+ for (size_t i = 0; i < thumbs.size(); i++)
+ {
+ CFileItemPtr item(new CFileItem(StringUtils::Format("thumb://Remote%i", i), false));
+ item->SetArt("thumb", thumbs[i]);
+ item->SetIconImage("DefaultPicture.png");
+ item->SetLabel(g_localizeStrings.Get(13513));
+ items.Add(item);
+
+ // TODO: Do we need to clear the cached image?
+ // CTextureCache::Get().ClearCachedImage(thumbs[i]);
+ }
+
+ if (type == "actor")
+ {
+ CStdString picturePath;
+ CStdString strThumb = URIUtils::AddFileToFolder(picturePath, "folder.jpg");
+ if (XFILE::CFile::Exists(strThumb))
+ {
+ CFileItemPtr pItem(new CFileItem(strThumb,false));
+ pItem->SetLabel(g_localizeStrings.Get(13514));
+ pItem->SetArt("thumb", strThumb);
+ items.Add(pItem);
+ local = true;
+ }
+ else
+ noneitem->SetIconImage("DefaultActor.png");
+ }
+
+ if (type == "set")
+ noneitem->SetIconImage("DefaultVideo.png");
+ }
+ else
+ {
+ CStdString strThumb = URIUtils::AddFileToFolder(artistPath, "folder.jpg");
+ if (XFILE::CFile::Exists(strThumb))
+ {
+ CFileItemPtr pItem(new CFileItem(strThumb, false));
+ pItem->SetLabel(g_localizeStrings.Get(13514));
+ pItem->SetArt("thumb", strThumb);
+ items.Add(pItem);
+ local = true;
+ }
+ else
+ noneitem->SetIconImage("DefaultArtist.png");
+ }
+
+ if (!local)
+ items.Add(noneitem);
+
+ CStdString result;
+ VECSOURCES sources=*CMediaSourceSettings::Get().GetSources("video");
+ g_mediaManager.GetLocalDrives(sources);
+ AddItemPathToFileBrowserSources(sources, *item);
+ if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(13511), result))
+ return false; // user cancelled
+
+ if (result == "thumb://Current")
+ result = currentThumb; // user chose the one they have
+
+ // delete the thumbnail if that's what the user wants, else overwrite with the
+ // new thumbnail
+ if (result == "thumb://None")
+ result.clear();
+ else if (StringUtils::StartsWith(result, "thumb://Remote"))
+ {
+ int number = atoi(StringUtils::Mid(result, 14).c_str());
+ result = thumbs[number];
+ }
+
+ // write the selected artwork to the database
+ if (type == "set" ||
+ type == "actor" ||
+ type == "season" ||
+ (type == "artist" && idArtist < 0))
+ videodb.SetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artType, result);
+ else
+ {
+ CMusicDatabase musicdb;
+ if (musicdb.Open())
+ musicdb.SetArtForItem(idArtist, "artist", artType, result);
+ }
+
+ CUtil::DeleteVideoDatabaseDirectoryCache();
+ CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
+ g_windowManager.SendMessage(msg);
+
+ return true;
+}
+
+std::string CGUIDialogVideoInfo::GetLocalizedVideoType(const std::string &strType)
+{
+ if (strType == "movie" || strType == "movies")
+ return g_localizeStrings.Get(20342);
+ else if (strType == "tvshow" || strType == "tvshows")
+ return g_localizeStrings.Get(20343);
+ else if (strType == "episode" || strType == "episodes")
+ return g_localizeStrings.Get(20359);
+ else if (strType == "musicvideo" || strType == "musicvideos")
+ return g_localizeStrings.Get(20391);
+
+ return "";
+}
+
bool CGUIDialogVideoInfo::UpdateVideoItemSortTitle(const CFileItemPtr &pItem)
{
// dont allow update while scanning
return false;
}
+
+bool CGUIDialogVideoInfo::OnGetFanart(const CFileItemPtr &videoItem)
+{
+ if (videoItem == NULL || !videoItem->HasVideoInfoTag())
+ return false;
+
+ // update the db
+ CVideoDatabase videodb;
+ if (!videodb.Open())
+ return false;
+
+ CVideoThumbLoader loader;
+ CFileItem item(*videoItem);
+ loader.LoadItem(&item);
+
+ CFileItemList items;
+ if (item.HasArt("fanart"))
+ {
+ CFileItemPtr itemCurrent(new CFileItem("fanart://Current", false));
+ itemCurrent->SetArt("thumb", item.GetArt("fanart"));
+ itemCurrent->SetLabel(g_localizeStrings.Get(20440));
+ items.Add(itemCurrent);
+ }
+
+ // add the none option
+ {
+ CFileItemPtr itemNone(new CFileItem("fanart://None", false));
+ itemNone->SetIconImage("DefaultVideo.png");
+ itemNone->SetLabel(g_localizeStrings.Get(20439));
+ items.Add(itemNone);
+ }
+
+ CStdString result;
+ VECSOURCES sources(*CMediaSourceSettings::Get().GetSources("video"));
+ g_mediaManager.GetLocalDrives(sources);
+ AddItemPathToFileBrowserSources(sources, item);
+ bool flip = false;
+ if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445) ||
+ StringUtils::EqualsNoCase(result, "fanart://Current"))
+ return false;
+
+ if (StringUtils::EqualsNoCase(result, "fanart://None") || !CFile::Exists(result))
+ result.clear();
+ if (!result.empty() && flip)
+ result = CTextureUtils::GetWrappedImageURL(result, "", "flipped");
+
+ videodb.SetArtForItem(item.GetVideoInfoTag()->m_iDbId, item.GetVideoInfoTag()->m_type, "fanart", result);
+
+ // clear view cache and reload images
+ CUtil::DeleteVideoDatabaseDirectoryCache();
+
+ return true;
+}
static int ManageVideoItem(const CFileItemPtr &item);
static bool UpdateVideoItemTitle(const CFileItemPtr &pItem);
static bool MarkWatched(const CFileItemPtr &item, bool bMark);
+ static bool CanDeleteVideoItem(const CFileItemPtr &item);
+ static bool DeleteVideoItemFromDatabase(const CFileItemPtr &item, bool unavailable = false);
+ static bool DeleteVideoItem(const CFileItemPtr &item, bool unavailable = false);
+ static bool ManageMovieSets(const CFileItemPtr &item);
static bool GetMoviesForSet(const CFileItem *setItem, CFileItemList &originalMovies, CFileItemList &selectedMovies);
static bool GetSetForMovie(const CFileItem *movieItem, CFileItemPtr &selectedSet);
static bool SetMovieSet(const CFileItem *movieItem, const CFileItem *selectedSet);
+
+ static bool GetItemsForTag(const CStdString &strHeading, const std::string &type, CFileItemList &items, int idTag = -1, bool showAll = true);
+ static bool AddItemsToTag(const CFileItemPtr &tagItem);
+ static bool RemoveItemsFromTag(const CFileItemPtr &tagItem);
+
+ static bool ManageVideoItemArtwork(const CFileItemPtr &item, const std::string &type);
+
+ static std::string GetLocalizedVideoType(const std::string &strType);
protected:
virtual void OnInitWindow();
void Update();
static bool UpdateVideoItemSortTitle(const CFileItemPtr &pItem);
static bool LinkMovieToTvShow(const CFileItemPtr &item, bool bRemove, CVideoDatabase &database);
+ /*! \brief Pop up a fanart chooser. Does not utilise remote URLs.
+ \param videoItem the item to choose fanart for.
+ */
+ static bool OnGetFanart(const CFileItemPtr &videoItem);
+
CFileItemPtr m_movieItem;
CFileItemList *m_castList;
bool m_bViewReview;
buttons.Add(CONTEXT_BUTTON_PLAY_PART, 20324);
}
- if (!m_vecItems->GetPath().empty() && !StringUtils::StartsWithNoCase(item->GetPath(), "newsmartplaylist://") && !StringUtils::StartsWithNoCase(item->GetPath(), "newtag://")
- && !m_vecItems->IsSourcesPath())
- {
- buttons.Add(CONTEXT_BUTTON_QUEUE_ITEM, 13347); // Add to Playlist
- }
-
// allow a folder to be ad-hoc queued and played by the default player
if (item->m_bIsFolder || (item->IsPlayList() &&
!g_advancedSettings.m_playlistAsFolders))
{
buttons.Add(CONTEXT_BUTTON_PLAY_ITEM, 208);
}
+
+ if (!m_vecItems->GetPath().empty() && !StringUtils::StartsWithNoCase(item->GetPath(), "newsmartplaylist://") && !StringUtils::StartsWithNoCase(item->GetPath(), "newtag://")
+ && !m_vecItems->IsSourcesPath())
+ {
+ buttons.Add(CONTEXT_BUTTON_QUEUE_ITEM, 13347); // Add to Playlist
+ }
}
if (!m_vecItems->IsPlugin() && (item->IsPlugin() || item->IsScript()))
CGUIWindowVideoBase::OnInfo(pItem,scraper);
}
-bool CGUIWindowVideoNav::CanDelete(const CStdString& strPath)
-{
- CQueryParams params;
- CVideoDatabaseDirectory::GetQueryParams(strPath,params);
-
- if (params.GetMovieId() != -1 ||
- params.GetEpisodeId() != -1 ||
- params.GetMVideoId() != -1 ||
- (params.GetTvShowId() != -1 && params.GetSeason() <= -1
- && !CVideoDatabaseDirectory::IsAllItem(strPath)))
- return true;
-
- return false;
-}
-
void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
{
if (m_vecItems->IsParentFolder())
}
else
{
- if (!DeleteItem(pItem.get()))
+ if (!CGUIDialogVideoInfo::DeleteVideoItem(pItem))
return;
-
- CStdString strDeletePath;
- if (pItem->m_bIsFolder)
- strDeletePath=pItem->GetVideoInfoTag()->m_strPath;
- else
- strDeletePath=pItem->GetVideoInfoTag()->m_strFileNameAndPath;
-
- if (URIUtils::GetFileName(strDeletePath).Equals("VIDEO_TS.IFO"))
- {
- strDeletePath = URIUtils::GetDirectory(strDeletePath);
- if (StringUtils::EndsWithNoCase(strDeletePath, "video_ts/"))
- {
- URIUtils::RemoveSlashAtEnd(strDeletePath);
- strDeletePath = URIUtils::GetDirectory(strDeletePath);
- }
- }
- if (URIUtils::HasSlashAtEnd(strDeletePath))
- pItem->m_bIsFolder=true;
-
- if (CSettings::Get().GetBool("filelists.allowfiledeletion") &&
- CUtil::SupportsWriteFileOperations(strDeletePath))
- {
- pItem->SetPath(strDeletePath);
- CGUIWindowVideoBase::OnDeleteItem(pItem);
- }
}
CUtil::DeleteVideoDatabaseDirectoryCache();
}
-bool CGUIWindowVideoNav::DeleteItem(CFileItem* pItem, bool bUnavailable /* = false */)
-{
- if (!pItem->HasVideoInfoTag() || !CanDelete(pItem->GetPath()))
- return false;
-
- VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES;
- if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_strShowTitle.empty())
- iType = VIDEODB_CONTENT_TVSHOWS;
- if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iSeason > -1 && !pItem->m_bIsFolder)
- iType = VIDEODB_CONTENT_EPISODES;
- if (pItem->HasVideoInfoTag() && !pItem->GetVideoInfoTag()->m_artist.empty())
- iType = VIDEODB_CONTENT_MUSICVIDEOS;
-
- // dont allow update while scanning
- if (g_application.IsVideoScanning())
- {
- CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
- return false;
- }
-
-
- CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
- if (!pDialog)
- return false;
- if (iType == VIDEODB_CONTENT_MOVIES)
- pDialog->SetHeading(432);
- if (iType == VIDEODB_CONTENT_EPISODES)
- pDialog->SetHeading(20362);
- if (iType == VIDEODB_CONTENT_TVSHOWS)
- pDialog->SetHeading(20363);
- if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
- pDialog->SetHeading(20392);
-
- if(bUnavailable)
- {
- pDialog->SetLine(0, g_localizeStrings.Get(662));
- pDialog->SetLine(1, g_localizeStrings.Get(663));
- pDialog->SetLine(2, "");;
- pDialog->DoModal();
- }
- else
- {
- CStdString strLine = StringUtils::Format(g_localizeStrings.Get(433), pItem->GetLabel().c_str());
- pDialog->SetLine(0, strLine);
- pDialog->SetLine(1, "");
- pDialog->SetLine(2, "");;
- pDialog->DoModal();
- }
-
- if (!pDialog->IsConfirmed())
- return false;
-
- CStdString path;
- CVideoDatabase database;
- database.Open();
-
- database.GetFilePathById(pItem->GetVideoInfoTag()->m_iDbId, path, iType);
- if (path.empty())
- return false;
- if (iType == VIDEODB_CONTENT_MOVIES)
- database.DeleteMovie(path);
- if (iType == VIDEODB_CONTENT_EPISODES)
- database.DeleteEpisode(path, pItem->GetVideoInfoTag()->m_iDbId);
- if (iType == VIDEODB_CONTENT_TVSHOWS)
- database.DeleteTvShow(path);
- if (iType == VIDEODB_CONTENT_MUSICVIDEOS)
- database.DeleteMusicVideo(path);
-
- if (iType == VIDEODB_CONTENT_TVSHOWS)
- database.SetPathHash(path,"");
- else
- database.SetPathHash(URIUtils::GetDirectory(path), "");
-
- return true;
-}
-
void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
{
CFileItemPtr item;
// can we update the database?
if (CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
{
- if (node == NODE_TYPE_TITLE_TVSHOWS)
- {
- if (g_application.IsVideoScanning())
- buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
- else
- buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
- }
if (!item->IsPlugin() && !item->IsScript() && !item->IsLiveTV() && !item->IsAddonsPath() &&
item->GetPath() != "sources://video/" &&
item->GetPath() != "special://videoplaylists/" &&
}
}
if (!g_application.IsVideoScanning() && item->IsVideoDb() && item->HasVideoInfoTag() &&
- (!item->m_bIsFolder || m_vecItems->GetContent().Equals("movies") || m_vecItems->GetContent().Equals("tvshows")))
+ (item->GetVideoInfoTag()->m_type == "movie" || // movies
+ item->GetVideoInfoTag()->m_type == "tvshow" || // tvshows
+ item->GetVideoInfoTag()->m_type == "episode" || // episodes
+ item->GetVideoInfoTag()->m_type == "musicvideo" || // musicvideos
+ item->GetVideoInfoTag()->m_type == "tag" || // tags
+ item->GetVideoInfoTag()->m_type == "set")) // sets
{
buttons.Add(CONTEXT_BUTTON_EDIT, 16106);
}
-
- if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
- buttons.Add(CONTEXT_BUTTON_SET_SEASON_ART, 13511);
-
- if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://movies/sets/") && item->GetPath().size() > 22 && item->m_bIsFolder) // sets
+ if (node == NODE_TYPE_TITLE_TVSHOWS)
{
- buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_ART, 13511);
- buttons.Add(CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS, 20465);
- buttons.Add(CONTEXT_BUTTON_DELETE, 646);
+ if (g_application.IsVideoScanning())
+ buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
+ else
+ buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
}
- if (m_vecItems->GetContent() == "tags" && item->m_bIsFolder) // tags
- {
- CVideoDbUrl videoUrl;
- if (videoUrl.FromString(item->GetPath()))
- {
- std::string mediaType = videoUrl.GetItemType();
-
- CStdString strLabelAdd = StringUtils::Format(g_localizeStrings.Get(20460), GetLocalizedType(videoUrl.GetItemType()).c_str());
- CStdString strLabelRemove = StringUtils::Format(g_localizeStrings.Get(20461), GetLocalizedType(videoUrl.GetItemType()).c_str());
- buttons.Add(CONTEXT_BUTTON_TAGS_ADD_ITEMS, strLabelAdd);
- buttons.Add(CONTEXT_BUTTON_TAGS_REMOVE_ITEMS, strLabelRemove);
- buttons.Add(CONTEXT_BUTTON_DELETE, 646);
- }
- }
+ if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
+ buttons.Add(CONTEXT_BUTTON_SET_SEASON_ART, 13511);
if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder)
{
else
buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
}
- if (item->IsVideoDb() && item->HasVideoInfoTag() &&
- (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS))
- buttons.Add(CONTEXT_BUTTON_DELETE, 646);
}
if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
}
}
-// predicate used by sorting and set_difference
-bool compFileItemsByDbId(const CFileItemPtr& lhs, const CFileItemPtr& rhs)
-{
- return lhs->HasVideoInfoTag() && rhs->HasVideoInfoTag() && lhs->GetVideoInfoTag()->m_iDbId < rhs->GetVideoInfoTag()->m_iDbId;
-}
-
bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
CFileItemPtr item;
case CONTEXT_BUTTON_SET_SEASON_ART:
case CONTEXT_BUTTON_SET_ACTOR_THUMB:
case CONTEXT_BUTTON_SET_ARTIST_THUMB:
- case CONTEXT_BUTTON_SET_MOVIESET_ART:
{
- // Grab the thumbnails from the web
- CFileItemList items;
- CFileItemPtr noneitem(new CFileItem("thumb://None", false));
- CStdString currentThumb;
- int idArtist = -1;
- CStdString artistPath;
- string artType = "thumb";
- if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
- {
- CMusicDatabase database;
- database.Open();
- idArtist = database.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
- database.GetArtistPath(idArtist, artistPath);
- currentThumb = database.GetArtForItem(idArtist, "artist", "thumb");
- if (currentThumb.empty())
- currentThumb = m_database.GetArtForItem(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_type, artType);
- }
- else if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
- currentThumb = m_database.GetArtForItem(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_type, artType);
- else
- { // SEASON, SET
- map<string, string> currentArt;
- artType = CGUIDialogVideoInfo::ChooseArtType(*m_vecItems->Get(itemNumber), currentArt);
- if (artType.empty())
- return false;
-
- if (artType == "fanart")
- {
- OnChooseFanart(*m_vecItems->Get(itemNumber));
- return true;
- }
-
- if (currentArt.find(artType) != currentArt.end())
- currentThumb = currentArt[artType];
- else if ((artType == "poster" || artType == "banner") && currentArt.find("thumb") != currentArt.end())
- currentThumb = currentArt["thumb"];
- }
- if (!currentThumb.empty())
- {
- CFileItemPtr item(new CFileItem("thumb://Current", false));
- item->SetArt("thumb", currentThumb);
- item->SetLabel(g_localizeStrings.Get(13512));
- items.Add(item);
- }
- noneitem->SetIconImage("DefaultFolder.png");
- noneitem->SetLabel(g_localizeStrings.Get(13515));
-
- vector<CStdString> thumbs;
- if (button != CONTEXT_BUTTON_SET_ARTIST_THUMB)
- {
- CVideoInfoTag tag;
- if (button == CONTEXT_BUTTON_SET_SEASON_ART)
- m_database.GetTvShowInfo("",tag,m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iIdShow);
- else
- tag = *m_vecItems->Get(itemNumber)->GetVideoInfoTag();
- if (button == CONTEXT_BUTTON_SET_SEASON_ART)
- tag.m_strPictureURL.GetThumbURLs(thumbs, artType, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iSeason);
- else
- tag.m_strPictureURL.GetThumbURLs(thumbs, artType);
-
- for (unsigned int i = 0; i < thumbs.size(); i++)
- {
- CStdString strItemPath = StringUtils::Format("thumb://Remote%i",i);
- CFileItemPtr item(new CFileItem(strItemPath, false));
- item->SetArt("thumb", thumbs[i]);
- item->SetIconImage("DefaultPicture.png");
- item->SetLabel(g_localizeStrings.Get(13513));
- items.Add(item);
-
- // TODO: Do we need to clear the cached image?
- // CTextureCache::Get().ClearCachedImage(thumbs[i]);
- }
- }
-
- bool local=false;
- if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
- {
- CStdString strThumb = URIUtils::AddFileToFolder(artistPath, "folder.jpg");
- if (XFILE::CFile::Exists(strThumb))
- {
- CFileItemPtr pItem(new CFileItem(strThumb,false));
- pItem->SetLabel(g_localizeStrings.Get(13514));
- pItem->SetArt("thumb", strThumb);
- items.Add(pItem);
- local = true;
- }
- else
- noneitem->SetIconImage("DefaultArtist.png");
- }
-
+ std::string type = "season";
if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
- {
- CStdString picturePath;
- CStdString strThumb = URIUtils::AddFileToFolder(picturePath, "folder.jpg");
- if (XFILE::CFile::Exists(strThumb))
- {
- CFileItemPtr pItem(new CFileItem(strThumb,false));
- pItem->SetLabel(g_localizeStrings.Get(13514));
- pItem->SetArt("thumb", strThumb);
- items.Add(pItem);
- local = true;
- }
- else
- noneitem->SetIconImage("DefaultActor.png");
- }
-
- if (button == CONTEXT_BUTTON_SET_MOVIESET_ART)
- noneitem->SetIconImage("DefaultVideo.png");
-
- if (!local)
- items.Add(noneitem);
-
- VECSOURCES sources=*CMediaSourceSettings::Get().GetSources("video");
- g_mediaManager.GetLocalDrives(sources);
- CStdString result;
- CGUIDialogVideoInfo::AddItemPathToFileBrowserSources(sources, *item);
- if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources,
- g_localizeStrings.Get(13511), result))
- {
- return false; // user cancelled
- }
-
- if (result == "thumb://Current")
- result = currentThumb; // user chose the one they have
-
- // delete the thumbnail if that's what the user wants, else overwrite with the
- // new thumbnail
- if (StringUtils::StartsWith(result, "thumb://Remote"))
- {
- int number = atoi(result.substr(14).c_str());
- result = thumbs[number];
- }
- else if (result == "thumb://None")
- result.clear();
- if (button == CONTEXT_BUTTON_SET_MOVIESET_ART ||
- button == CONTEXT_BUTTON_SET_ACTOR_THUMB ||
- button == CONTEXT_BUTTON_SET_SEASON_ART ||
- (button == CONTEXT_BUTTON_SET_ARTIST_THUMB && idArtist < 0))
- m_database.SetArtForItem(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_iDbId, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_type, artType, result);
- else
- {
- CMusicDatabase db;
- if (db.Open())
- db.SetArtForItem(idArtist, "artist", artType, result);
- }
-
- CUtil::DeleteVideoDatabaseDirectoryCache();
- CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
- g_windowManager.SendMessage(msg);
- Refresh();
-
- return true;
- }
- case CONTEXT_BUTTON_TAGS_ADD_ITEMS:
- {
- CVideoDbUrl videoUrl;
- if (!videoUrl.FromString(item->GetPath()))
- return false;
-
- std::string mediaType = videoUrl.GetItemType();
- mediaType = mediaType.substr(0, mediaType.length() - 1);
-
- CFileItemList items;
- CStdString localizedType = GetLocalizedType(mediaType);
- CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(20464), localizedType.c_str());
- if (!GetItemsForTag(strLabel, mediaType, items, item->GetVideoInfoTag()->m_iDbId))
- return true;
-
- CVideoDatabase videodb;
- if (!videodb.Open())
- return true;
-
- for (int index = 0; index < items.Size(); index++)
- {
- if (!items[index]->HasVideoInfoTag() || items[index]->GetVideoInfoTag()->m_iDbId <= 0)
- continue;
-
- videodb.AddTagToItem(items[index]->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_iDbId, mediaType);
- }
-
- // we need to clear any cached version of this tag's listing
- items.SetPath(item->GetPath());
- items.RemoveDiscCache(GetID());
- return true;
- }
- case CONTEXT_BUTTON_TAGS_REMOVE_ITEMS:
- {
- CVideoDbUrl videoUrl;
- if (!videoUrl.FromString(item->GetPath()))
- return false;
+ type = "actor";
+ else if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
+ type = "artist";
- std::string mediaType = videoUrl.GetItemType();
- mediaType = mediaType.substr(0, mediaType.length() - 1);
-
- CFileItemList items;
- CStdString localizedType = GetLocalizedType(mediaType);
- CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(20464), localizedType.c_str());
- if (!GetItemsForTag(strLabel, mediaType, items, item->GetVideoInfoTag()->m_iDbId, false))
- return true;
-
- CVideoDatabase videodb;
- if (!videodb.Open())
- return true;
-
- for (int index = 0; index < items.Size(); index++)
- {
- if (!items[index]->HasVideoInfoTag() || items[index]->GetVideoInfoTag()->m_iDbId <= 0)
- continue;
-
- videodb.RemoveTagFromItem(items[index]->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_iDbId, mediaType);
- }
-
- // we need to clear any cached version of this tag's listing
- items.SetPath(item->GetPath());
- items.RemoveDiscCache(GetID());
- return true;
- }
- case CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS:
- {
- CFileItemList originalItems;
- CFileItemList selectedItems;
-
- if (!CGUIDialogVideoInfo::GetMoviesForSet(item.get(), originalItems, selectedItems) || selectedItems.Size() == 0) // need at least one item selected
- return true;
- VECFILEITEMS original = originalItems.GetList();
- std::sort(original.begin(), original.end(), compFileItemsByDbId);
- VECFILEITEMS selected = selectedItems.GetList();
- std::sort(selected.begin(), selected.end(), compFileItemsByDbId);
-
- bool refreshNeeded = false;
- // update the "added" items
- VECFILEITEMS addedItems;
- set_difference(selected.begin(),selected.end(), original.begin(),original.end(), std::back_inserter(addedItems), compFileItemsByDbId);
- for (VECFILEITEMS::iterator it = addedItems.begin(); it != addedItems.end(); ++it)
- {
- if (CGUIDialogVideoInfo::SetMovieSet(it->get(), item.get()))
- refreshNeeded = true;
- }
- // update the "deleted" items
- CFileItemPtr clearItem(new CFileItem());
- clearItem->GetVideoInfoTag()->m_iDbId = -1; // -1 will be used to clear set
- VECFILEITEMS deletedItems;
- set_difference(original.begin(),original.end(), selected.begin(),selected.end(), std::back_inserter(deletedItems), compFileItemsByDbId);
- for (VECFILEITEMS::iterator it = deletedItems.begin(); it != deletedItems.end(); ++it)
- {
- if (CGUIDialogVideoInfo::SetMovieSet(it->get(), clearItem.get()))
- refreshNeeded = true;
- }
+ bool result = CGUIDialogVideoInfo::ManageVideoItemArtwork(m_vecItems->Get(itemNumber), type);
+ Refresh();
- // we need to clear any cached version of this tag's listing
- if (refreshNeeded)
- Refresh();
- return true;
+ return result;
}
case CONTEXT_BUTTON_GO_TO_ARTIST:
{
return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
}
-void CGUIWindowVideoNav::OnChooseFanart(const CFileItem &videoItem)
-{
- if (!videoItem.HasVideoInfoTag())
- return;
-
- CFileItem item(videoItem);
-
- CFileItemList items;
-
- CVideoThumbLoader loader;
- loader.LoadItem(&item);
-
- if (item.HasArt("fanart"))
- {
- CFileItemPtr itemCurrent(new CFileItem("fanart://Current",false));
- itemCurrent->SetArt("thumb", item.GetArt("fanart"));
- itemCurrent->SetLabel(g_localizeStrings.Get(20440));
- items.Add(itemCurrent);
- }
-
- // add the none option
- {
- CFileItemPtr itemNone(new CFileItem("fanart://None", false));
- itemNone->SetIconImage("DefaultVideo.png");
- itemNone->SetLabel(g_localizeStrings.Get(20439));
- items.Add(itemNone);
- }
-
- CStdString result;
- VECSOURCES sources(*CMediaSourceSettings::Get().GetSources("video"));
- g_mediaManager.GetLocalDrives(sources);
- CGUIDialogVideoInfo::AddItemPathToFileBrowserSources(sources, item);
- bool flip=false;
- if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445) || result.Equals("fanart://Current"))
- return;
-
- if (result.Equals("fanart://None") || !CFile::Exists(result))
- result.clear();
- if (!result.empty() && flip)
- result = CTextureUtils::GetWrappedImageURL(result, "", "flipped");
-
- // update the db
- CVideoDatabase db;
- if (db.Open())
- {
- db.SetArtForItem(item.GetVideoInfoTag()->m_iDbId, item.GetVideoInfoTag()->m_type, "fanart", result);
- db.Close();
- }
-
- // clear view cache and reload images
- CUtil::DeleteVideoDatabaseDirectoryCache();
-
- Refresh();
-}
-
bool CGUIWindowVideoNav::OnClick(int iItem)
{
CFileItemPtr item = m_vecItems->Get(iItem);
if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
{
CLog::Log(LOGDEBUG, "%s called on '%s' but file doesn't exist", __FUNCTION__, item->GetPath().c_str());
- if (!DeleteItem(item.get(), true))
+ if (!CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(item, true))
return true;
// update list
// get the media type and convert from plural to singular (by removing the trailing "s")
CStdString mediaType = item->GetPath().substr(9);
mediaType = mediaType.substr(0, mediaType.size() - 1);
- CStdString localizedType = GetLocalizedType(mediaType);
+ CStdString localizedType = CGUIDialogVideoInfo::GetLocalizedVideoType(mediaType);
if (localizedType.empty())
return true;
int idTag = videodb.AddTag(strTag);
CFileItemList items;
CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(20464), localizedType.c_str());
- if (GetItemsForTag(strLabel, mediaType, items, idTag))
+ if (CGUIDialogVideoInfo::GetItemsForTag(strLabel, mediaType, items, idTag))
{
for (int index = 0; index < items.Size(); index++)
{
return listchanged;
}
-
-bool CGUIWindowVideoNav::GetItemsForTag(const CStdString &strHeading, const std::string &type, CFileItemList &items, int idTag /* = -1 */, bool showAll /* = true */)
-{
- CVideoDatabase videodb;
- if (!videodb.Open())
- return false;
-
- MediaType mediaType = MediaTypeNone;
- std::string baseDir = "videodb://";
- std::string idColumn;
- if (type.compare("movie") == 0)
- {
- mediaType = MediaTypeMovie;
- baseDir += "movies";
- idColumn = "idMovie";
- }
- else if (type.compare("tvshow") == 0)
- {
- mediaType = MediaTypeTvShow;
- baseDir += "tvshows";
- idColumn = "idShow";
- }
- else if (type.compare("musicvideo") == 0)
- {
- mediaType = MediaTypeMusicVideo;
- baseDir += "musicvideos";
- idColumn = "idMVideo";
- }
-
- baseDir += "/titles/";
- CVideoDbUrl videoUrl;
- if (!videoUrl.FromString(baseDir))
- return false;
-
- CVideoDatabase::Filter filter;
- if (idTag > 0)
- {
- if (!showAll)
- videoUrl.AddOption("tagid", idTag);
- else
- filter.where = videodb.PrepareSQL("%sview.%s NOT IN (SELECT taglinks.idMedia FROM taglinks WHERE taglinks.idTag = %d AND taglinks.media_type = '%s')", type.c_str(), idColumn.c_str(), idTag, type.c_str());
- }
-
- CFileItemList listItems;
- if (!videodb.GetSortedVideos(mediaType, videoUrl.ToString(), SortDescription(), listItems, filter) || listItems.Size() <= 0)
- return false;
-
- CGUIDialogSelect *dialog = (CGUIDialogSelect *)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
- if (dialog == NULL)
- return false;
-
- listItems.Sort(SortByLabel, SortOrderAscending, SortAttributeIgnoreArticle);
-
- dialog->Reset();
- dialog->SetMultiSelection(true);
- dialog->SetHeading(strHeading);
- dialog->SetItems(&listItems);
- dialog->EnableButton(true, 186);
- dialog->DoModal();
-
- items.Copy(dialog->GetSelectedItems());
- return items.Size() > 0;
-}
-
-CStdString CGUIWindowVideoNav::GetLocalizedType(const std::string &strType)
-{
- if (strType == "movie" || strType == "movies")
- return g_localizeStrings.Get(20342);
- else if (strType == "tvshow" || strType == "tvshows")
- return g_localizeStrings.Get(20343);
- else if (strType == "episode" || strType == "episodes")
- return g_localizeStrings.Get(20359);
- else if (strType == "musicvideo" || strType == "musicvideos")
- return g_localizeStrings.Get(20391);
- else
- return "";
-}
virtual bool OnMessage(CGUIMessage& message);
virtual void OnInfo(CFileItem* pItem, ADDON::ScraperPtr &info);
- static bool CanDelete(const CStdString& strPath);
- static bool DeleteItem(CFileItem* pItem, bool bUnavailable=false);
/*! \brief Load video information from the database for these items (public static version)
Useful for grabbing information for file listings, from watched status to full metadata
*/
void LoadVideoInfo(CFileItemList &items);
- /*! \brief Pop up a fanart chooser. Does not utilise remote URLs.
- \param videoItem the item to choose fanart for.
- */
- void OnChooseFanart(const CFileItem &videoItem);
-
bool ApplyWatchedFilter(CFileItemList &items);
virtual bool GetFilteredItems(const CStdString &filter, CFileItemList &items);
virtual CStdString GetQuickpathName(const CStdString& strPath) const;
- bool GetItemsForTag(const CStdString &strHeading, const std::string &type, CFileItemList &items, int idTag = -1, bool showAll = true);
- static CStdString GetLocalizedType(const std::string &strType);
-
VECSOURCES m_shares;
};