m_movieItem->m_dateTime = m_movieItem->GetVideoInfoTag()->m_premiered;
if(m_movieItem->GetVideoInfoTag()->m_iYear == 0 && m_movieItem->m_dateTime.IsValid())
m_movieItem->GetVideoInfoTag()->m_iYear = m_movieItem->m_dateTime.GetYear();
- m_movieItem->SetProperty("totalepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode);
- 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
- m_movieItem->SetProperty("watchedepisodes", m_movieItem->GetVideoInfoTag()->m_playCount);
- m_movieItem->SetProperty("unwatchedepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode - m_movieItem->GetVideoInfoTag()->m_playCount);
- m_movieItem->GetVideoInfoTag()->m_playCount = (m_movieItem->GetVideoInfoTag()->m_iEpisode == m_movieItem->GetVideoInfoTag()->m_playCount) ? 1 : 0;
+ if (!m_movieItem->HasProperty("totalepisodes"))
+ {
+ m_movieItem->SetProperty("totalepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode);
+ 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
+ m_movieItem->SetProperty("watchedepisodes", m_movieItem->GetVideoInfoTag()->m_playCount);
+ m_movieItem->SetProperty("unwatchedepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode - m_movieItem->GetVideoInfoTag()->m_playCount);
+ m_movieItem->GetVideoInfoTag()->m_playCount = (m_movieItem->GetVideoInfoTag()->m_iEpisode == m_movieItem->GetVideoInfoTag()->m_playCount) ? 1 : 0;
+ }
}
else if (type == VIDEODB_CONTENT_EPISODES)
{
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 == "movie" || type == "tvshow")
buttons.Add(CONTEXT_BUTTON_EDIT_SORTTITLE, 16107);
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;
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->HasVideoInfoTag())
+ if (pItem == NULL || !pItem->HasVideoInfoTag())
return false;
// dont allow update while scanning
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 params.GetMovieId() != -1 ||
params.GetEpisodeId() != -1 ||
params.GetMVideoId() != -1 ||
+ params.GetSetId() != -1 ||
(params.GetTvShowId() != -1 && params.GetSeason() <= -1 &&
!CVideoDatabaseDirectory::IsAllItem(item->GetPath()));
}
bool CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(const CFileItemPtr &item, bool unavailable /* = false */)
{
- if (!item->HasVideoInfoTag() || !CanDeleteVideoItem(item))
+ if (item == NULL || !item->HasVideoInfoTag() ||
+ !CanDeleteVideoItem(item))
return false;
// dont allow update while scanning
case VIDEODB_CONTENT_MUSICVIDEOS:
heading = 20392;
break;
+ case VIDEODB_CONTENT_MOVIE_SETS:
+ heading = 646;
+ break;
default:
return false;
if (!pDialog->IsConfirmed())
return false;
- CStdString path;
CVideoDatabase database;
database.Open();
+ if (type == VIDEODB_CONTENT_MOVIE_SETS)
+ {
+ database.DeleteSet(item->GetVideoInfoTag()->m_iDbId);
+ return true;
+ }
+
+ CStdString path;
database.GetFilePathById(item->GetVideoInfoTag()->m_iDbId, path, type);
if (path.empty())
return false;
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() ||
// 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);
+ CFileUtils::DeleteItem(item);
}
}
CUtil::DeleteVideoDatabaseDirectoryCache();
- return result;
+ return true;
}
bool CGUIDialogVideoInfo::ManageMovieSets(const CFileItemPtr &item)
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())
+ return false;
+
CVideoDatabase videodb;
if (!videodb.Open())
return false;
CFileItemList listItems;
CStdString baseDir = "videodb://movies/sets/";
- if (!CDirectory::GetDirectory(baseDir, listItems) || listItems.Size() <= 0)
+ if (!CDirectory::GetDirectory(baseDir, listItems))
return false;
listItems.Sort(SortByLabel, SortOrderAscending, SortAttributeIgnoreArticle);
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 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
}
int iSelectedLabel = 0;
- if (list.Size() > 1)
+ if (list.Size() > 1 || (!bRemove && !list.IsEmpty()))
{
list.Sort(SortByLabel, SortOrderAscending, CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);
CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
iSelectedLabel = pDialog->GetSelectedLabel();
}
- if (iSelectedLabel > -1)
+ if (iSelectedLabel > -1 && iSelectedLabel < list.Size())
return database.LinkMovieToTvshow(dbId, list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove);
return false;