diff options
27 files changed, 963 insertions, 722 deletions
diff --git a/addons/skin.confluence/720p/MyMusicNav.xml b/addons/skin.confluence/720p/MyMusicNav.xml index 41c69952cc..193f99418a 100644 --- a/addons/skin.confluence/720p/MyMusicNav.xml +++ b/addons/skin.confluence/720p/MyMusicNav.xml @@ -57,9 +57,9 @@ <include>SideBladeLeft</include> <control type="grouplist" id="9000"> <posx>0</posx> - <posy>110</posy> + <posy>60</posy> <width>250</width> - <height>600</height> + <height>650</height> <onleft>9000</onleft> <onright>50</onright> <onup>9000</onup> @@ -109,7 +109,7 @@ <include>ButtonCommonValues</include> <label>587</label> </control> - <control type="radiobutton" id="20"> + <control type="radiobutton" id="98"> <visible>Container.CanFilterAdvanced</visible> <description>Filter</description> <include>ButtonCommonValues</include> @@ -146,6 +146,24 @@ <label>589</label> <include>ButtonCommonValues</include> </control> + <control type="label" id="203"> + <width>250</width> + <height>35</height> + <font>font12</font> + <label>31039</label> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + </control> + <control type="togglebutton" id="20"> + <description>Update library</description> + <include>ButtonCommonValues</include> + <label>653</label> + <altlabel>13353</altlabel> + <alttexturefocus border="5">button-focus.png</alttexturefocus> + <alttexturenofocus>-</alttexturenofocus> + <usealttexture>library.isscanningvideo</usealttexture> + </control> <include>CommonNowPlaying_Controls</include> </control> </control> diff --git a/addons/skin.confluence/720p/MyVideoNav.xml b/addons/skin.confluence/720p/MyVideoNav.xml index af4c338f85..52acab4d03 100644 --- a/addons/skin.confluence/720p/MyVideoNav.xml +++ b/addons/skin.confluence/720p/MyVideoNav.xml @@ -61,9 +61,9 @@ <include>SideBladeLeft</include> <control type="grouplist" id="9000"> <posx>0</posx> - <posy>110</posy> + <posy>60</posy> <width>250</width> - <height>600</height> + <height>650</height> <onleft>9000</onleft> <onright>50</onright> <onup>9000</onup> @@ -106,7 +106,7 @@ <include>ButtonCommonValues</include> <label>587</label> </control> - <control type="radiobutton" id="20"> + <control type="radiobutton" id="98"> <visible>Container.CanFilterAdvanced</visible> <description>Filter</description> <include>ButtonCommonValues</include> @@ -144,18 +144,6 @@ <include>ButtonCommonValues</include> <label>137</label> </control> - <control type="radiobutton" id="7"> - <description>Stack Toggle</description> - <textwidth>170</textwidth> - <include>ButtonCommonValues</include> - <label>346</label> - </control> - <control type="radiobutton" id="17"> - <description>Flatten</description> - <textwidth>170</textwidth> - <include>ButtonCommonValues</include> - <label>20411</label> - </control> <control type="radiobutton" id="16"> <description>PartyMode</description> <label>589</label> @@ -171,6 +159,24 @@ <selected>system.ismaster</selected> <visible>system.haslocks</visible> </control> + <control type="label" id="203"> + <width>250</width> + <height>35</height> + <font>font12</font> + <label>31039</label> + <textcolor>blue</textcolor> + <align>center</align> + <aligny>center</aligny> + </control> + <control type="togglebutton" id="20"> + <description>Update library</description> + <include>ButtonCommonValues</include> + <label>653</label> + <altlabel>13353</altlabel> + <alttexturefocus border="5">button-focus.png</alttexturefocus> + <alttexturenofocus>-</alttexturenofocus> + <usealttexture>library.isscanningvideo</usealttexture> + </control> <include>CommonNowPlaying_Controls</include> </control> </control> diff --git a/addons/skin.confluence/720p/MyWeather.xml b/addons/skin.confluence/720p/MyWeather.xml index e8997170a8..75d2550f36 100644 --- a/addons/skin.confluence/720p/MyWeather.xml +++ b/addons/skin.confluence/720p/MyWeather.xml @@ -724,9 +724,9 @@ <include>SideBladeLeft</include> <control type="grouplist" id="9000"> <posx>0</posx> - <posy>110</posy> + <posy>60</posy> <width>250</width> - <height>610</height> + <height>650</height> <onleft>9000</onleft> <onright>50</onright> <onup>9000</onup> diff --git a/addons/skin.confluence/720p/includes.xml b/addons/skin.confluence/720p/includes.xml index 2a412c6b89..c5be31437a 100644 --- a/addons/skin.confluence/720p/includes.xml +++ b/addons/skin.confluence/720p/includes.xml @@ -29,6 +29,10 @@ <value condition="!IsEmpty(ListItem.Art(poster))">$INFO[ListItem.Art(poster)]</value> <value condition="IsEmpty(ListItem.Art(poster))">$INFO[ListItem.Icon]</value> </variable> + <variable name="PlayList"> + <value condition="Player.HasVideo">ActivateWindow(videoplaylist)</value> + <value condition="Player.HasAudio">ActivateWindow(musicplaylist)</value> + </variable> <include name="BehindDialogFadeOut"> <control type="image"> @@ -149,7 +153,7 @@ <control type="image"> <description>LOGO</description> <posx>15</posx> - <posy>50</posy> + <posy>0</posy> <width>220</width> <height>80</height> <aspectratio>keep</aspectratio> @@ -888,6 +892,15 @@ <textureradionofocus>GoFullscreen.png</textureradionofocus> <visible>Player.HasMedia</visible> </control> + <control type="button" id="612"> + <description>Go to playlist</description> + <include>ButtonCommonValues</include> + <label>13350</label> + <onclick>$VAR[PlayList]</onclick> + <visible>Player.HasMedia</visible> + <visible>!VideoPlayer.Content(LiveTV)</visible> + <visible>!Window.IsVisible(MusicPlaylist) + !Window.IsVisible(VideoPlaylist)</visible> + </control> </include> <include name="ScrollOffsetLabel"> <control type="group"> diff --git a/addons/skin.confluence/language/English/strings.po b/addons/skin.confluence/language/English/strings.po index b903155bf8..bf121efb86 100644 --- a/addons/skin.confluence/language/English/strings.po +++ b/addons/skin.confluence/language/English/strings.po @@ -102,7 +102,12 @@ msgctxt "#31033" msgid "Info" msgstr "" -#empty strings from id 31034 to 31039 +#empty strings from id 31034 to 31038 + +msgctxt "#31039" +msgid "Actions" +msgstr "" + #Extra labels msgctxt "#31040" diff --git a/language/English/strings.po b/language/English/strings.po index 438f8ea593..0042682a5e 100644 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -6719,7 +6719,15 @@ msgctxt "#16105" msgid "Edit title" msgstr "" -#empty strings from id 16106 to 16199 +msgctxt "#16106" +msgid "Manage ..." +msgstr "" + +msgctxt "#16107" +msgid "Edit sort title" +msgstr "" + +#empty strings from id 16108 to 16199 #: xbmc/windows/GUIWindowFileManager.cpp msgctxt "#16200" @@ -9981,7 +9989,10 @@ msgctxt "#20434" msgid "Sets" msgstr "" -#empty string with id 20435 +#: system/settings/settings.xml +msgctxt "#20435" +msgid "Combine split video items" +msgstr "" msgctxt "#20436" msgid "Export actor thumbs?" @@ -10070,7 +10081,10 @@ msgctxt "#20455" msgid "Listeners" msgstr "" -#empty string with id 20456 +#: system/settings/settings.xml +msgctxt "#20456" +msgid "Flatten library hierarchy" +msgstr "" msgctxt "#20457" msgid "Movie set" @@ -12972,12 +12986,12 @@ msgstr "" #: system/settings/settings.xml msgctxt "#36182" -msgid "No info available yet." +msgid "Enables direct playback of videos that are in folders, without having to open those folders first, as well as displaying multi-part video files as single items in non-library views." msgstr "" #: system/settings/settings.xml msgctxt "#36183" -msgid "No info available yet." +msgid "Removes the title, genre etc nodes from the library view. Selecting a category takes you straight to the title view." msgstr "" #: system/settings/settings.xml diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 81228fa137..2bad9bb969 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -598,12 +598,12 @@ <level>4</level> <default>100024</default> <!-- WINDOW_VIDEO_FILES --> </setting> - <setting id="myvideos.stackvideos" type="boolean" label="0" help="36182"> - <level>4</level> + <setting id="myvideos.stackvideos" type="boolean" label="20435" help="36182"> + <level>1</level> <default>false</default> </setting> - <setting id="myvideos.flatten" type="boolean" label="0" help="36183"> - <level>4</level> + <setting id="myvideos.flatten" type="boolean" label="20456" help="36183"> + <level>1</level> <default>false</default> </setting> </group> diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp index 957c8b3354..5e953188b4 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -31,6 +31,7 @@ #include "filesystem/MultiPathDirectory.h" #include "filesystem/MusicDatabaseDirectory.h" #include "filesystem/VideoDatabaseDirectory.h" +#include "filesystem/VideoDatabaseDirectory/QueryParams.h" #include "music/tags/MusicInfoTagLoaderFactory.h" #include "CueDocument.h" #include "video/VideoDatabase.h" @@ -941,6 +942,14 @@ bool CFileItem::IsSmartPlayList() const return URIUtils::HasExtension(m_strPath, ".xsp"); } +bool CFileItem::IsLibraryFolder() const +{ + if (HasProperty("library.filter") && GetProperty("library.filter").asBoolean()) + return true; + + return URIUtils::IsLibraryFolder(m_strPath); +} + bool CFileItem::IsPlayList() const { return CPlayListFactory::IsPlaylist(*this); @@ -3264,9 +3273,16 @@ int CFileItem::GetVideoContentType() const if (HasVideoInfoTag() && !GetVideoInfoTag()->m_strShowTitle.IsEmpty()) // tvshow type = VIDEODB_CONTENT_TVSHOWS; if (HasVideoInfoTag() && GetVideoInfoTag()->m_iSeason > -1 && !m_bIsFolder) // episode - type = VIDEODB_CONTENT_EPISODES; - if (HasVideoInfoTag() && !GetVideoInfoTag()->m_artist.empty()) - type = VIDEODB_CONTENT_MUSICVIDEOS; + return VIDEODB_CONTENT_EPISODES; + if (HasVideoInfoTag() && !GetVideoInfoTag()->m_artist.empty()) // music video + return VIDEODB_CONTENT_MUSICVIDEOS; + + CVideoDatabaseDirectory dir; + VIDEODATABASEDIRECTORY::CQueryParams params; + dir.GetQueryParams(m_strPath, params); + if (params.GetSetId() != -1 && params.GetMovieId() == -1) // movie set + return VIDEODB_CONTENT_MOVIE_SETS; + return type; } diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 4253fe1234..3d9c565105 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -147,6 +147,7 @@ public: bool IsInternetStream(const bool bStrictCheck = false) const; bool IsPlayList() const; bool IsSmartPlayList() const; + bool IsLibraryFolder() const; bool IsPythonScript() const; bool IsPlugin() const; bool IsScript() const; diff --git a/xbmc/addons/GUIWindowAddonBrowser.cpp b/xbmc/addons/GUIWindowAddonBrowser.cpp index 33c9a2be21..ca31201fc0 100644 --- a/xbmc/addons/GUIWindowAddonBrowser.cpp +++ b/xbmc/addons/GUIWindowAddonBrowser.cpp @@ -157,7 +157,7 @@ void CGUIWindowAddonBrowser::GetContextButtons(int itemNumber, if (addon->Type() == ADDON_REPOSITORY && pItem->m_bIsFolder) { buttons.Add(CONTEXT_BUTTON_SCAN,24034); - buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY,24035); + buttons.Add(CONTEXT_BUTTON_REFRESH,24035); } buttons.Add(CONTEXT_BUTTON_INFO,24003); @@ -185,7 +185,7 @@ bool CGUIWindowAddonBrowser::OnContextButton(int itemNumber, if (button == CONTEXT_BUTTON_SETTINGS) return CGUIDialogAddonSettings::ShowAndGetInput(addon); - if (button == CONTEXT_BUTTON_UPDATE_LIBRARY) + if (button == CONTEXT_BUTTON_REFRESH) { CAddonDatabase database; database.Open(); diff --git a/xbmc/dialogs/GUIDialogContextMenu.h b/xbmc/dialogs/GUIDialogContextMenu.h index 822f57c6ea..fff3b24ded 100644 --- a/xbmc/dialogs/GUIDialogContextMenu.h +++ b/xbmc/dialogs/GUIDialogContextMenu.h @@ -75,13 +75,11 @@ enum CONTEXT_BUTTON { CONTEXT_BUTTON_CANCELLED = 0, CONTEXT_BUTTON_INFO, CONTEXT_BUTTON_INFO_ALL, CONTEXT_BUTTON_CDDB, - CONTEXT_BUTTON_UPDATE_LIBRARY, - CONTEXT_BUTTON_UPDATE_TVSHOW, + CONTEXT_BUTTON_REFRESH, CONTEXT_BUTTON_SCAN, CONTEXT_BUTTON_STOP_SCANNING, CONTEXT_BUTTON_SET_ARTIST_THUMB, CONTEXT_BUTTON_SET_SEASON_ART, - CONTEXT_BUTTON_NOW_PLAYING, CONTEXT_BUTTON_CANCEL_PARTYMODE, CONTEXT_BUTTON_MARK_WATCHED, CONTEXT_BUTTON_MARK_UNWATCHED, @@ -129,6 +127,7 @@ enum CONTEXT_BUTTON { CONTEXT_BUTTON_CANCELLED = 0, CONTEXT_BUTTON_SET_MOVIESET, CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS, CONTEXT_BUTTON_BROWSE_INTO, + CONTEXT_BUTTON_EDIT_SORTTITLE, CONTEXT_BUTTON_USER1, CONTEXT_BUTTON_USER2, CONTEXT_BUTTON_USER3, diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp index 172d72f6ad..875a3f21c4 100644 --- a/xbmc/music/windows/GUIWindowMusicBase.cpp +++ b/xbmc/music/windows/GUIWindowMusicBase.cpp @@ -741,8 +741,6 @@ void CGUIWindowMusicBase::GetNonContextButtons(CContextButtons &buttons) { if (!m_vecItems->IsVirtualDirectoryRoot()) buttons.Add(CONTEXT_BUTTON_GOTO_ROOT, 20128); - if (g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC).size() > 0) - buttons.Add(CONTEXT_BUTTON_NOW_PLAYING, 13350); buttons.Add(CONTEXT_BUTTON_SETTINGS, 5); } @@ -809,10 +807,6 @@ bool CGUIWindowMusicBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) return true; } - case CONTEXT_BUTTON_NOW_PLAYING: - g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST); - return true; - case CONTEXT_BUTTON_GOTO_ROOT: Update(""); return true; diff --git a/xbmc/music/windows/GUIWindowMusicNav.cpp b/xbmc/music/windows/GUIWindowMusicNav.cpp index 94d392f706..ef34b82587 100644 --- a/xbmc/music/windows/GUIWindowMusicNav.cpp +++ b/xbmc/music/windows/GUIWindowMusicNav.cpp @@ -31,6 +31,7 @@ #include "playlists/PlayListFactory.h" #include "profiles/ProfilesManager.h" #include "video/VideoDatabase.h" +#include "video/dialogs/GUIDialogVideoInfo.h" #include "video/windows/GUIWindowVideoNav.h" #include "music/tags/MusicInfoTag.h" #include "guilib/GUIWindowManager.h" @@ -72,6 +73,8 @@ using namespace MUSICDATABASEDIRECTORY; #define CONTROL_BTN_FILTER 19 #define CONTROL_LABELEMPTY 18 +#define CONTROL_UPDATE_LIBRARY 20 + CGUIWindowMusicNav::CGUIWindowMusicNav(void) : CGUIWindowMusicBase(WINDOW_MUSIC_NAV, "MyMusicNav.xml") { @@ -165,6 +168,14 @@ bool CGUIWindowMusicNav::OnMessage(CGUIMessage& message) SetProperty("search", search); return true; } + else if (iControl == CONTROL_UPDATE_LIBRARY) + { + if (!g_application.IsMusicScanning()) + g_application.StartMusicScan(""); + else + g_application.StopMusicScan(); + return true; + } } break; case GUI_MSG_PLAYBACK_STOPPED: @@ -381,6 +392,8 @@ void CGUIWindowMusicNav::UpdateButtons() SET_CONTROL_LABEL(CONTROL_FILTER, strLabel); SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled()); + + CONTROL_ENABLE_ON_CONDITION(CONTROL_UPDATE_LIBRARY, !m_vecItems->IsAddonsPath() && !m_vecItems->IsPlugin() && !m_vecItems->IsScript()); } void CGUIWindowMusicNav::PlayItem(int iItem) @@ -535,14 +548,6 @@ void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &butt } // noncontextual buttons - if (g_application.IsMusicScanning()) - buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning - else - { - if (!m_vecItems->IsPlugin()) - buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653); - } - CGUIWindowMusicBase::GetNonContextButtons(buttons); } @@ -610,12 +615,6 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) OnInfoAll(itemNumber); return true; - case CONTEXT_BUTTON_UPDATE_LIBRARY: - { - g_application.StartMusicScan(""); - return true; - } - case CONTEXT_BUTTON_SET_DEFAULT: CSettings::Get().SetString("mymusic.defaultlibview", GetQuickpathName(item->GetPath())); CSettings::Get().Save(); @@ -647,19 +646,19 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) } case CONTEXT_BUTTON_MARK_WATCHED: - CGUIWindowVideoBase::MarkWatched(item,true); + CGUIDialogVideoInfo::MarkWatched(item, true); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; case CONTEXT_BUTTON_MARK_UNWATCHED: - CGUIWindowVideoBase::MarkWatched(item,false); + CGUIDialogVideoInfo::MarkWatched(item, false); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; case CONTEXT_BUTTON_RENAME: - CGUIWindowVideoBase::UpdateVideoTitle(item.get()); + CGUIDialogVideoInfo::UpdateVideoItemTitle(item); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; diff --git a/xbmc/utils/DatabaseUtils.cpp b/xbmc/utils/DatabaseUtils.cpp index cd8b6a774b..44f60a7955 100644 --- a/xbmc/utils/DatabaseUtils.cpp +++ b/xbmc/utils/DatabaseUtils.cpp @@ -84,6 +84,33 @@ MediaType DatabaseUtils::MediaTypeFromString(const std::string &strMediaType) return MediaTypeNone; } +MediaType DatabaseUtils::MediaTypeFromVideoContentType(int videoContentType) +{ + VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)videoContentType; + switch (type) + { + case VIDEODB_CONTENT_MOVIES: + return MediaTypeMovie; + + case VIDEODB_CONTENT_MOVIE_SETS: + return MediaTypeVideoCollection; + + case VIDEODB_CONTENT_TVSHOWS: + return MediaTypeTvShow; + + case VIDEODB_CONTENT_EPISODES: + return MediaTypeEpisode; + + case VIDEODB_CONTENT_MUSICVIDEOS: + return MediaTypeMusicVideo; + + default: + break; + } + + return MediaTypeNone; +} + std::string DatabaseUtils::GetField(Field field, MediaType mediaType, DatabaseQueryPart queryPart) { if (field == FieldNone || mediaType == MediaTypeNone) @@ -275,184 +302,20 @@ std::string DatabaseUtils::GetField(Field field, MediaType mediaType, DatabaseQu return ""; } -int DatabaseUtils::GetFieldIndex(Field field, MediaType mediaType) +int DatabaseUtils::GetField(Field field, MediaType mediaType) { if (field == FieldNone || mediaType == MediaTypeNone) return -1; - int index = -1; - - if (mediaType == MediaTypeAlbum) - { - if (field == FieldId) return CMusicDatabase::album_idAlbum; - else if (field == FieldAlbum) return CMusicDatabase::album_strAlbum; - else if (field == FieldArtist || field == FieldAlbumArtist) return CMusicDatabase::album_strArtists; - else if (field == FieldGenre) return CMusicDatabase::album_strGenres; - else if (field == FieldYear) return CMusicDatabase::album_iYear; - else if (field == FieldMoods) return CMusicDatabase::album_strMoods; - else if (field == FieldStyles) return CMusicDatabase::album_strStyles; - else if (field == FieldThemes) return CMusicDatabase::album_strThemes; - else if (field == FieldReview) return CMusicDatabase::album_strReview; - else if (field == FieldMusicLabel) return CMusicDatabase::album_strLabel; - else if (field == FieldAlbumType) return CMusicDatabase::album_strType; - else if (field == FieldRating) return CMusicDatabase::album_iRating; - else if (field == FieldPlaycount) return CMusicDatabase::album_iTimesPlayed; - } - else if (mediaType == MediaTypeSong) - { - if (field == FieldId) return CMusicDatabase::song_idSong; - else if (field == FieldTitle) return CMusicDatabase::song_strTitle; - else if (field == FieldTrackNumber) return CMusicDatabase::song_iTrack; - else if (field == FieldTime) return CMusicDatabase::song_iDuration; - else if (field == FieldYear) return CMusicDatabase::song_iYear; - else if (field == FieldFilename) return CMusicDatabase::song_strFileName; - else if (field == FieldPlaycount) return CMusicDatabase::song_iTimesPlayed; - else if (field == FieldStartOffset) return CMusicDatabase::song_iStartOffset; - else if (field == FieldEndOffset) return CMusicDatabase::song_iEndOffset; - else if (field == FieldLastPlayed) return CMusicDatabase::song_lastplayed; - else if (field == FieldRating) return CMusicDatabase::song_rating; - else if (field == FieldComment) return CMusicDatabase::song_comment; - else if (field == FieldAlbum) return CMusicDatabase::song_strAlbum; - else if (field == FieldPath) return CMusicDatabase::song_strPath; - else if (field == FieldGenre) return CMusicDatabase::song_strGenres; - else if (field == FieldArtist || field == FieldAlbumArtist) return CMusicDatabase::song_strArtists; - } - else if (mediaType == MediaTypeArtist) - { - if (field == FieldId) return CMusicDatabase::artist_idArtist; - else if (field == FieldArtist) return CMusicDatabase::artist_strArtist; - else if (field == FieldGenre) return CMusicDatabase::artist_strGenres; - else if (field == FieldMoods) return CMusicDatabase::artist_strMoods; - else if (field == FieldStyles) return CMusicDatabase::artist_strStyles; - else if (field == FieldInstruments) return CMusicDatabase::artist_strInstruments; - else if (field == FieldBiography) return CMusicDatabase::artist_strBiography; - else if (field == FieldBorn) return CMusicDatabase::artist_strBorn; - else if (field == FieldBandFormed) return CMusicDatabase::artist_strFormed; - else if (field == FieldDisbanded) return CMusicDatabase::artist_strDisbanded; - else if (field == FieldDied) return CMusicDatabase::artist_strDied; - } - else if (mediaType == MediaTypeMusicVideo) - { - if (field == FieldId) return 0; - else if (field == FieldTitle) index = VIDEODB_ID_MUSICVIDEO_TITLE; - else if (field == FieldTime) index = VIDEODB_ID_MUSICVIDEO_RUNTIME; - else if (field == FieldDirector) index = VIDEODB_ID_MUSICVIDEO_DIRECTOR; - else if (field == FieldStudio) index = VIDEODB_ID_MUSICVIDEO_STUDIOS; - else if (field == FieldYear) index = VIDEODB_ID_MUSICVIDEO_YEAR; - else if (field == FieldPlot) index = VIDEODB_ID_MUSICVIDEO_PLOT; - else if (field == FieldAlbum) index = VIDEODB_ID_MUSICVIDEO_ALBUM; - else if (field == FieldArtist) index = VIDEODB_ID_MUSICVIDEO_ARTIST; - else if (field == FieldGenre) index = VIDEODB_ID_MUSICVIDEO_GENRE; - else if (field == FieldTrackNumber) index = VIDEODB_ID_MUSICVIDEO_TRACK; - else if (field == FieldFilename) return VIDEODB_DETAILS_MUSICVIDEO_FILE; - else if (field == FieldPath) return VIDEODB_DETAILS_MUSICVIDEO_PATH; - else if (field == FieldPlaycount) return VIDEODB_DETAILS_MUSICVIDEO_PLAYCOUNT; - else if (field == FieldLastPlayed) return VIDEODB_DETAILS_MUSICVIDEO_LASTPLAYED; - else if (field == FieldDateAdded) return VIDEODB_DETAILS_MUSICVIDEO_DATEADDED; - - if (index < 0) - return index; - - // see VideoDatabase.h - // the first field is the item's ID and the second is the item's file ID - index += 2; - } - else if (mediaType == MediaTypeMovie) - { - if (field == FieldId) return 0; - else if (field == FieldTitle) index = VIDEODB_ID_TITLE; - else if (field == FieldSortTitle) index = VIDEODB_ID_SORTTITLE; - else if (field == FieldPlot) index = VIDEODB_ID_PLOT; - else if (field == FieldPlotOutline) index = VIDEODB_ID_PLOTOUTLINE; - else if (field == FieldTagline) index = VIDEODB_ID_TAGLINE; - else if (field == FieldVotes) index = VIDEODB_ID_VOTES; - else if (field == FieldRating) index = VIDEODB_ID_RATING; - else if (field == FieldWriter) index = VIDEODB_ID_CREDITS; - else if (field == FieldYear) index = VIDEODB_ID_YEAR; - else if (field == FieldTime) index = VIDEODB_ID_RUNTIME; - else if (field == FieldMPAA) index = VIDEODB_ID_MPAA; - else if (field == FieldTop250) index = VIDEODB_ID_TOP250; - else if (field == FieldSet) return VIDEODB_DETAILS_MOVIE_SET_NAME; - else if (field == FieldGenre) index = VIDEODB_ID_GENRE; - else if (field == FieldDirector) index = VIDEODB_ID_DIRECTOR; - else if (field == FieldStudio) index = VIDEODB_ID_STUDIOS; - else if (field == FieldTrailer) index = VIDEODB_ID_TRAILER; - else if (field == FieldCountry) index = VIDEODB_ID_COUNTRY; - else if (field == FieldFilename) index = VIDEODB_DETAILS_MOVIE_FILE; - else if (field == FieldPath) return VIDEODB_DETAILS_MOVIE_PATH; - else if (field == FieldPlaycount) return VIDEODB_DETAILS_MOVIE_PLAYCOUNT; - else if (field == FieldLastPlayed) return VIDEODB_DETAILS_MOVIE_LASTPLAYED; - else if (field == FieldDateAdded) return VIDEODB_DETAILS_MOVIE_DATEADDED; - - if (index < 0) - return index; - - // see VideoDatabase.h - // the first field is the item's ID and the second is the item's file ID - index += 2; - } - else if (mediaType == MediaTypeTvShow) - { - if (field == FieldId) return 0; - else if (field == FieldTitle) index = VIDEODB_ID_TV_TITLE; - else if (field == FieldSortTitle) index = VIDEODB_ID_TV_SORTTITLE; - else if (field == FieldPlot) index = VIDEODB_ID_TV_PLOT; - else if (field == FieldTvShowStatus) index = VIDEODB_ID_TV_STATUS; - else if (field == FieldVotes) index = VIDEODB_ID_TV_VOTES; - else if (field == FieldRating) index = VIDEODB_ID_TV_RATING; - else if (field == FieldYear) index = VIDEODB_ID_TV_PREMIERED; - else if (field == FieldGenre) index = VIDEODB_ID_TV_GENRE; - else if (field == FieldMPAA) index = VIDEODB_ID_TV_MPAA; - else if (field == FieldStudio) index = VIDEODB_ID_TV_STUDIOS; - else if (field == FieldPath) return VIDEODB_DETAILS_TVSHOW_PATH; - else if (field == FieldDateAdded) return VIDEODB_DETAILS_TVSHOW_DATEADDED; - else if (field == FieldLastPlayed) return VIDEODB_DETAILS_TVSHOW_LASTPLAYED; - else if (field == FieldNumberOfEpisodes) return VIDEODB_DETAILS_TVSHOW_NUM_EPISODES; - else if (field == FieldNumberOfWatchedEpisodes) return VIDEODB_DETAILS_TVSHOW_NUM_WATCHED; - else if (field == FieldSeason) return VIDEODB_DETAILS_TVSHOW_NUM_SEASONS; - - if (index < 0) - return index; - - // see VideoDatabase.h - // the first field is the item's ID - index += 1; - } - else if (mediaType == MediaTypeEpisode) - { - if (field == FieldId) return 0; - else if (field == FieldTitle) index = VIDEODB_ID_EPISODE_TITLE; - else if (field == FieldPlot) index = VIDEODB_ID_EPISODE_PLOT; - else if (field == FieldVotes) index = VIDEODB_ID_EPISODE_VOTES; - else if (field == FieldRating) index = VIDEODB_ID_EPISODE_RATING; - else if (field == FieldWriter) index = VIDEODB_ID_EPISODE_CREDITS; - else if (field == FieldAirDate) index = VIDEODB_ID_EPISODE_AIRED; - else if (field == FieldTime) index = VIDEODB_ID_EPISODE_RUNTIME; - else if (field == FieldDirector) index = VIDEODB_ID_EPISODE_DIRECTOR; - else if (field == FieldSeason) index = VIDEODB_ID_EPISODE_SEASON; - else if (field == FieldEpisodeNumber) index = VIDEODB_ID_EPISODE_EPISODE; - else if (field == FieldUniqueId) index = VIDEODB_ID_EPISODE_UNIQUEID; - else if (field == FieldEpisodeNumberSpecialSort) index = VIDEODB_ID_EPISODE_SORTEPISODE; - else if (field == FieldSeasonSpecialSort) index = VIDEODB_ID_EPISODE_SORTSEASON; - else if (field == FieldFilename) return VIDEODB_DETAILS_EPISODE_FILE; - else if (field == FieldPath) return VIDEODB_DETAILS_EPISODE_PATH; - else if (field == FieldPlaycount) return VIDEODB_DETAILS_EPISODE_PLAYCOUNT; - else if (field == FieldLastPlayed) return VIDEODB_DETAILS_EPISODE_LASTPLAYED; - else if (field == FieldDateAdded) return VIDEODB_DETAILS_EPISODE_DATEADDED; - else if (field == FieldTvShowTitle) return VIDEODB_DETAILS_EPISODE_TVSHOW_NAME; - else if (field == FieldStudio) return VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO; - else if (field == FieldYear) return VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED; - else if (field == FieldMPAA) return VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA; - - if (index < 0) - return index; + return GetField(field, mediaType, false); +} - // see VideoDatabase.h - // the first field is the item's ID and the second is the item's file ID - index += 2; - } +int DatabaseUtils::GetFieldIndex(Field field, MediaType mediaType) +{ + if (field == FieldNone || mediaType == MediaTypeNone) + return -1; - return index; + return GetField(field, mediaType, true); } bool DatabaseUtils::GetSelectFields(const Fields &fields, MediaType mediaType, FieldList &selectFields) @@ -674,3 +537,195 @@ std::string DatabaseUtils::BuildLimitClause(int end, int start /* = 0 */) return sql.str(); } + +int DatabaseUtils::GetField(Field field, MediaType mediaType, bool asIndex) +{ + if (field == FieldNone || mediaType == MediaTypeNone) + return -1; + + int index = -1; + + if (mediaType == MediaTypeAlbum) + { + if (field == FieldId) return CMusicDatabase::album_idAlbum; + else if (field == FieldAlbum) return CMusicDatabase::album_strAlbum; + else if (field == FieldArtist || field == FieldAlbumArtist) return CMusicDatabase::album_strArtists; + else if (field == FieldGenre) return CMusicDatabase::album_strGenres; + else if (field == FieldYear) return CMusicDatabase::album_iYear; + else if (field == FieldMoods) return CMusicDatabase::album_strMoods; + else if (field == FieldStyles) return CMusicDatabase::album_strStyles; + else if (field == FieldThemes) return CMusicDatabase::album_strThemes; + else if (field == FieldReview) return CMusicDatabase::album_strReview; + else if (field == FieldMusicLabel) return CMusicDatabase::album_strLabel; + else if (field == FieldAlbumType) return CMusicDatabase::album_strType; + else if (field == FieldRating) return CMusicDatabase::album_iRating; + else if (field == FieldPlaycount) return CMusicDatabase::album_iTimesPlayed; + } + else if (mediaType == MediaTypeSong) + { + if (field == FieldId) return CMusicDatabase::song_idSong; + else if (field == FieldTitle) return CMusicDatabase::song_strTitle; + else if (field == FieldTrackNumber) return CMusicDatabase::song_iTrack; + else if (field == FieldTime) return CMusicDatabase::song_iDuration; + else if (field == FieldYear) return CMusicDatabase::song_iYear; + else if (field == FieldFilename) return CMusicDatabase::song_strFileName; + else if (field == FieldPlaycount) return CMusicDatabase::song_iTimesPlayed; + else if (field == FieldStartOffset) return CMusicDatabase::song_iStartOffset; + else if (field == FieldEndOffset) return CMusicDatabase::song_iEndOffset; + else if (field == FieldLastPlayed) return CMusicDatabase::song_lastplayed; + else if (field == FieldRating) return CMusicDatabase::song_rating; + else if (field == FieldComment) return CMusicDatabase::song_comment; + else if (field == FieldAlbum) return CMusicDatabase::song_strAlbum; + else if (field == FieldPath) return CMusicDatabase::song_strPath; + else if (field == FieldGenre) return CMusicDatabase::song_strGenres; + else if (field == FieldArtist || field == FieldAlbumArtist) return CMusicDatabase::song_strArtists; + } + else if (mediaType == MediaTypeArtist) + { + if (field == FieldId) return CMusicDatabase::artist_idArtist; + else if (field == FieldArtist) return CMusicDatabase::artist_strArtist; + else if (field == FieldGenre) return CMusicDatabase::artist_strGenres; + else if (field == FieldMoods) return CMusicDatabase::artist_strMoods; + else if (field == FieldStyles) return CMusicDatabase::artist_strStyles; + else if (field == FieldInstruments) return CMusicDatabase::artist_strInstruments; + else if (field == FieldBiography) return CMusicDatabase::artist_strBiography; + else if (field == FieldBorn) return CMusicDatabase::artist_strBorn; + else if (field == FieldBandFormed) return CMusicDatabase::artist_strFormed; + else if (field == FieldDisbanded) return CMusicDatabase::artist_strDisbanded; + else if (field == FieldDied) return CMusicDatabase::artist_strDied; + } + else if (mediaType == MediaTypeMusicVideo) + { + if (field == FieldId) return 0; + else if (field == FieldTitle) index = VIDEODB_ID_MUSICVIDEO_TITLE; + else if (field == FieldTime) index = VIDEODB_ID_MUSICVIDEO_RUNTIME; + else if (field == FieldDirector) index = VIDEODB_ID_MUSICVIDEO_DIRECTOR; + else if (field == FieldStudio) index = VIDEODB_ID_MUSICVIDEO_STUDIOS; + else if (field == FieldYear) index = VIDEODB_ID_MUSICVIDEO_YEAR; + else if (field == FieldPlot) index = VIDEODB_ID_MUSICVIDEO_PLOT; + else if (field == FieldAlbum) index = VIDEODB_ID_MUSICVIDEO_ALBUM; + else if (field == FieldArtist) index = VIDEODB_ID_MUSICVIDEO_ARTIST; + else if (field == FieldGenre) index = VIDEODB_ID_MUSICVIDEO_GENRE; + else if (field == FieldTrackNumber) index = VIDEODB_ID_MUSICVIDEO_TRACK; + else if (field == FieldFilename) return VIDEODB_DETAILS_MUSICVIDEO_FILE; + else if (field == FieldPath) return VIDEODB_DETAILS_MUSICVIDEO_PATH; + else if (field == FieldPlaycount) return VIDEODB_DETAILS_MUSICVIDEO_PLAYCOUNT; + else if (field == FieldLastPlayed) return VIDEODB_DETAILS_MUSICVIDEO_LASTPLAYED; + else if (field == FieldDateAdded) return VIDEODB_DETAILS_MUSICVIDEO_DATEADDED; + + if (index < 0) + return index; + + if (asIndex) + { + // see VideoDatabase.h + // the first field is the item's ID and the second is the item's file ID + index += 2; + } + } + else if (mediaType == MediaTypeMovie) + { + if (field == FieldId) return 0; + else if (field == FieldTitle) index = VIDEODB_ID_TITLE; + else if (field == FieldSortTitle) index = VIDEODB_ID_SORTTITLE; + else if (field == FieldPlot) index = VIDEODB_ID_PLOT; + else if (field == FieldPlotOutline) index = VIDEODB_ID_PLOTOUTLINE; + else if (field == FieldTagline) index = VIDEODB_ID_TAGLINE; + else if (field == FieldVotes) index = VIDEODB_ID_VOTES; + else if (field == FieldRating) index = VIDEODB_ID_RATING; + else if (field == FieldWriter) index = VIDEODB_ID_CREDITS; + else if (field == FieldYear) index = VIDEODB_ID_YEAR; + else if (field == FieldTime) index = VIDEODB_ID_RUNTIME; + else if (field == FieldMPAA) index = VIDEODB_ID_MPAA; + else if (field == FieldTop250) index = VIDEODB_ID_TOP250; + else if (field == FieldSet) return VIDEODB_DETAILS_MOVIE_SET_NAME; + else if (field == FieldGenre) index = VIDEODB_ID_GENRE; + else if (field == FieldDirector) index = VIDEODB_ID_DIRECTOR; + else if (field == FieldStudio) index = VIDEODB_ID_STUDIOS; + else if (field == FieldTrailer) index = VIDEODB_ID_TRAILER; + else if (field == FieldCountry) index = VIDEODB_ID_COUNTRY; + else if (field == FieldFilename) index = VIDEODB_DETAILS_MOVIE_FILE; + else if (field == FieldPath) return VIDEODB_DETAILS_MOVIE_PATH; + else if (field == FieldPlaycount) return VIDEODB_DETAILS_MOVIE_PLAYCOUNT; + else if (field == FieldLastPlayed) return VIDEODB_DETAILS_MOVIE_LASTPLAYED; + else if (field == FieldDateAdded) return VIDEODB_DETAILS_MOVIE_DATEADDED; + + if (index < 0) + return index; + + if (asIndex) + { + // see VideoDatabase.h + // the first field is the item's ID and the second is the item's file ID + index += 2; + } + } + else if (mediaType == MediaTypeTvShow) + { + if (field == FieldId) return 0; + else if (field == FieldTitle) index = VIDEODB_ID_TV_TITLE; + else if (field == FieldSortTitle) index = VIDEODB_ID_TV_SORTTITLE; + else if (field == FieldPlot) index = VIDEODB_ID_TV_PLOT; + else if (field == FieldTvShowStatus) index = VIDEODB_ID_TV_STATUS; + else if (field == FieldVotes) index = VIDEODB_ID_TV_VOTES; + else if (field == FieldRating) index = VIDEODB_ID_TV_RATING; + else if (field == FieldYear) index = VIDEODB_ID_TV_PREMIERED; + else if (field == FieldGenre) index = VIDEODB_ID_TV_GENRE; + else if (field == FieldMPAA) index = VIDEODB_ID_TV_MPAA; + else if (field == FieldStudio) index = VIDEODB_ID_TV_STUDIOS; + else if (field == FieldPath) return VIDEODB_DETAILS_TVSHOW_PATH; + else if (field == FieldDateAdded) return VIDEODB_DETAILS_TVSHOW_DATEADDED; + else if (field == FieldLastPlayed) return VIDEODB_DETAILS_TVSHOW_LASTPLAYED; + else if (field == FieldNumberOfEpisodes) return VIDEODB_DETAILS_TVSHOW_NUM_EPISODES; + else if (field == FieldNumberOfWatchedEpisodes) return VIDEODB_DETAILS_TVSHOW_NUM_WATCHED; + else if (field == FieldSeason) return VIDEODB_DETAILS_TVSHOW_NUM_SEASONS; + + if (index < 0) + return index; + + if (asIndex) + { + // see VideoDatabase.h + // the first field is the item's ID + index += 1; + } + } + else if (mediaType == MediaTypeEpisode) + { + if (field == FieldId) return 0; + else if (field == FieldTitle) index = VIDEODB_ID_EPISODE_TITLE; + else if (field == FieldPlot) index = VIDEODB_ID_EPISODE_PLOT; + else if (field == FieldVotes) index = VIDEODB_ID_EPISODE_VOTES; + else if (field == FieldRating) index = VIDEODB_ID_EPISODE_RATING; + else if (field == FieldWriter) index = VIDEODB_ID_EPISODE_CREDITS; + else if (field == FieldAirDate) index = VIDEODB_ID_EPISODE_AIRED; + else if (field == FieldTime) index = VIDEODB_ID_EPISODE_RUNTIME; + else if (field == FieldDirector) index = VIDEODB_ID_EPISODE_DIRECTOR; + else if (field == FieldSeason) index = VIDEODB_ID_EPISODE_SEASON; + else if (field == FieldEpisodeNumber) index = VIDEODB_ID_EPISODE_EPISODE; + else if (field == FieldUniqueId) index = VIDEODB_ID_EPISODE_UNIQUEID; + else if (field == FieldEpisodeNumberSpecialSort) index = VIDEODB_ID_EPISODE_SORTEPISODE; + else if (field == FieldSeasonSpecialSort) index = VIDEODB_ID_EPISODE_SORTSEASON; + else if (field == FieldFilename) return VIDEODB_DETAILS_EPISODE_FILE; + else if (field == FieldPath) return VIDEODB_DETAILS_EPISODE_PATH; + else if (field == FieldPlaycount) return VIDEODB_DETAILS_EPISODE_PLAYCOUNT; + else if (field == FieldLastPlayed) return VIDEODB_DETAILS_EPISODE_LASTPLAYED; + else if (field == FieldDateAdded) return VIDEODB_DETAILS_EPISODE_DATEADDED; + else if (field == FieldTvShowTitle) return VIDEODB_DETAILS_EPISODE_TVSHOW_NAME; + else if (field == FieldStudio) return VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO; + else if (field == FieldYear) return VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED; + else if (field == FieldMPAA) return VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA; + + if (index < 0) + return index; + + if (asIndex) + { + // see VideoDatabase.h + // the first field is the item's ID and the second is the item's file ID + index += 2; + } + } + + return index; +} diff --git a/xbmc/utils/DatabaseUtils.h b/xbmc/utils/DatabaseUtils.h index ed7ee757cb..69b7fb664c 100644 --- a/xbmc/utils/DatabaseUtils.h +++ b/xbmc/utils/DatabaseUtils.h @@ -155,8 +155,10 @@ class DatabaseUtils public: static std::string MediaTypeToString(MediaType mediaType); static MediaType MediaTypeFromString(const std::string &strMediaType); + static MediaType MediaTypeFromVideoContentType(int videoContentType); static std::string GetField(Field field, MediaType mediaType, DatabaseQueryPart queryPart); + static int GetField(Field field, MediaType mediaType); static int GetFieldIndex(Field field, MediaType mediaType); static bool GetSelectFields(const Fields &fields, MediaType mediaType, FieldList &selectFields); @@ -164,4 +166,7 @@ public: static bool GetDatabaseResults(MediaType mediaType, const FieldList &fields, const std::auto_ptr<dbiplus::Dataset> &dataset, DatabaseResults &results); static std::string BuildLimitClause(int end, int start = 0); + +private: + static int GetField(Field field, MediaType mediaType, bool asIndex); }; diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 74027ebdac..a6da187f52 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -853,6 +853,12 @@ bool URIUtils::IsAndroidApp(const CStdString &path) return path.Left(11).Equals("androidapp:"); } +bool URIUtils::IsLibraryFolder(const CStdString& strFile) +{ + CURL url(strFile); + return url.GetProtocol().Equals("library"); +} + bool URIUtils::IsDOSPath(const CStdString &path) { if (path.size() > 1 && path[1] == ':' && isalpha(path[0])) diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h index cd9929fbdd..b0c8f9309c 100644 --- a/xbmc/utils/URIUtils.h +++ b/xbmc/utils/URIUtils.h @@ -114,6 +114,7 @@ public: static bool IsArchive(const CStdString& strFile); static bool IsBluray(const CStdString& strFile); static bool IsAndroidApp(const CStdString& strFile); + static bool IsLibraryFolder(const CStdString& strFile); static void AddSlashAtEnd(CStdString& strFolder); static bool HasSlashAtEnd(const CStdString& strFile, bool checkURL = false); diff --git a/xbmc/video/GUIViewStateVideo.cpp b/xbmc/video/GUIViewStateVideo.cpp index 303262c3f1..06a1805146 100644 --- a/xbmc/video/GUIViewStateVideo.cpp +++ b/xbmc/video/GUIViewStateVideo.cpp @@ -479,7 +479,7 @@ CGUIViewStateVideoMovies::CGUIViewStateVideoMovies(const CFileItemList& items) : AddSortMethod(SortByYear, 562, LABEL_MASKS("%T", "%Y", "%T", "%Y")); // Title, Year | Title, Year const CViewState *viewState = CViewStateSettings::Get().Get("videonavtitles"); - if (items.IsSmartPlayList() || items.GetProperty("library.filter").asBoolean()) + if (items.IsSmartPlayList() || items.IsLibraryFolder()) AddPlaylistOrder(items, LABEL_MASKS("%T", "%R", "%T", "%R")); // Title, Rating | Title, Rating else { @@ -516,7 +516,7 @@ CGUIViewStateVideoMusicVideos::CGUIViewStateVideoMusicVideos(const CFileItemList AddSortMethod(SortByTrackNumber, 554, LABEL_MASKS(strTrackLeft, strTrackRight)); // Userdefined, Userdefined | empty, empty const CViewState *viewState = CViewStateSettings::Get().Get("videonavmusicvideos"); - if (items.IsSmartPlayList() || items.GetProperty("library.filter").asBoolean()) + if (items.IsSmartPlayList() || items.IsLibraryFolder()) AddPlaylistOrder(items, LABEL_MASKS("%A - %T", "%Y")); // Artist - Title, Year | empty, empty else { @@ -541,7 +541,7 @@ CGUIViewStateVideoTVShows::CGUIViewStateVideoTVShows(const CFileItemList& items) AddSortMethod(SortByYear, 562, LABEL_MASKS("%T", "%Y", "%T", "%Y")); // Title, Year | Title, Year const CViewState *viewState = CViewStateSettings::Get().Get("videonavtvshows"); - if (items.IsSmartPlayList() || items.GetProperty("library.filter").asBoolean()) + if (items.IsSmartPlayList() || items.IsLibraryFolder()) AddPlaylistOrder(items, LABEL_MASKS("%T", "%M", "%T", "%M")); // Title, #Episodes | Title, #Episodes else { @@ -581,7 +581,7 @@ CGUIViewStateVideoEpisodes::CGUIViewStateVideoEpisodes(const CFileItemList& item } const CViewState *viewState = CViewStateSettings::Get().Get("videonavepisodes"); - if (items.IsSmartPlayList() || items.GetProperty("library.filter").asBoolean()) + if (items.IsSmartPlayList() || items.IsLibraryFolder()) AddPlaylistOrder(items, LABEL_MASKS("%Z - %H. %T", "%R")); // TvShow - Order. Title, Rating | empty, empty else { diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index 7afc740a03..fd2f999ca1 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -4702,40 +4702,38 @@ void CVideoDatabase::UpdateMovieTitle(int idMovie, const CStdString& strNewMovie if (NULL == m_pDB.get()) return ; if (NULL == m_pDS.get()) return ; CStdString content; - CStdString strSQL; if (iType == VIDEODB_CONTENT_MOVIES) { CLog::Log(LOGINFO, "Changing Movie:id:%i New Title:%s", idMovie, strNewMovieTitle.c_str()); - strSQL = PrepareSQL("UPDATE movie SET c%02d='%s' WHERE idMovie=%i", VIDEODB_ID_TITLE, strNewMovieTitle.c_str(), idMovie ); content = "movie"; } else if (iType == VIDEODB_CONTENT_EPISODES) { CLog::Log(LOGINFO, "Changing Episode:id:%i New Title:%s", idMovie, strNewMovieTitle.c_str()); - strSQL = PrepareSQL("UPDATE episode SET c%02d='%s' WHERE idEpisode=%i", VIDEODB_ID_EPISODE_TITLE, strNewMovieTitle.c_str(), idMovie ); content = "episode"; } else if (iType == VIDEODB_CONTENT_TVSHOWS) { CLog::Log(LOGINFO, "Changing TvShow:id:%i New Title:%s", idMovie, strNewMovieTitle.c_str()); - strSQL = PrepareSQL("UPDATE tvshow SET c%02d='%s' WHERE idShow=%i", VIDEODB_ID_TV_TITLE, strNewMovieTitle.c_str(), idMovie ); content = "tvshow"; } else if (iType == VIDEODB_CONTENT_MUSICVIDEOS) { CLog::Log(LOGINFO, "Changing MusicVideo:id:%i New Title:%s", idMovie, strNewMovieTitle.c_str()); - strSQL = PrepareSQL("UPDATE musicvideo SET c%02d='%s' WHERE idMVideo=%i", VIDEODB_ID_MUSICVIDEO_TITLE, strNewMovieTitle.c_str(), idMovie ); content = "musicvideo"; } else if (iType == VIDEODB_CONTENT_MOVIE_SETS) { CLog::Log(LOGINFO, "Changing Movie set:id:%i New Title:%s", idMovie, strNewMovieTitle.c_str()); - strSQL = PrepareSQL("UPDATE sets SET strSet='%s' WHERE idSet=%i", strNewMovieTitle.c_str(), idMovie ); + CStdString strSQL = PrepareSQL("UPDATE sets SET strSet='%s' WHERE idSet=%i", strNewMovieTitle.c_str(), idMovie ); + m_pDS->exec(strSQL.c_str()); } - m_pDS->exec(strSQL.c_str()); - if (content.size() > 0) + if (!content.empty()) + { + SetSingleValue(iType, idMovie, FieldTitle, strNewMovieTitle); AnnounceUpdate(content, idMovie); + } } catch (...) { @@ -4743,6 +4741,33 @@ void CVideoDatabase::UpdateMovieTitle(int idMovie, const CStdString& strNewMovie } } +bool CVideoDatabase::UpdateVideoSortTitle(int idDb, const CStdString& strNewSortTitle, VIDEODB_CONTENT_TYPE iType /* = VIDEODB_CONTENT_MOVIES */) +{ + try + { + if (NULL == m_pDB.get() || NULL == m_pDS.get()) + return false; + if (iType != VIDEODB_CONTENT_MOVIES && iType != VIDEODB_CONTENT_TVSHOWS) + return false; + + CStdString content = "movie"; + if (iType == VIDEODB_CONTENT_TVSHOWS) + content = "tvshow"; + + if (SetSingleValue(iType, idDb, FieldSortTitle, strNewSortTitle)) + { + AnnounceUpdate(content, idDb); + return true; + } + } + catch (...) + { + CLog::Log(LOGERROR, "%s (int idDb, const CStdString& strNewSortTitle, VIDEODB_CONTENT_TYPE iType) failed on ID: %i and Sort Title: %s", __FUNCTION__, idDb, strNewSortTitle.c_str()); + } + + return false; +} + /// \brief EraseVideoSettings() Erases the videoSettings table and reconstructs it void CVideoDatabase::EraseVideoSettings() { @@ -9146,42 +9171,84 @@ bool CVideoDatabase::CommitTransaction() return false; } -void CVideoDatabase::SetDetail(const CStdString& strDetail, int id, int field, - VIDEODB_CONTENT_TYPE type) +bool CVideoDatabase::SetSingleValue(VIDEODB_CONTENT_TYPE type, int dbId, int dbField, const std::string &strValue) { + string strSQL; try { - if (NULL == m_pDB.get()) return; - if (NULL == m_pDS.get()) return; + if (NULL == m_pDB.get() || NULL == m_pDS.get()) + return false; - CStdString strTable, strField; + string strTable, strField; if (type == VIDEODB_CONTENT_MOVIES) { strTable = "movie"; strField = "idMovie"; } - if (type == VIDEODB_CONTENT_TVSHOWS) + else if (type == VIDEODB_CONTENT_TVSHOWS) { strTable = "tvshow"; strField = "idShow"; } - if (type == VIDEODB_CONTENT_MUSICVIDEOS) + else if (type == VIDEODB_CONTENT_EPISODES) + { + strTable = "episode"; + strField = "idEpisode"; + } + else if (type == VIDEODB_CONTENT_MUSICVIDEOS) { strTable = "musicvideo"; strField = "idMVideo"; } - if (strTable.IsEmpty()) - return; + if (strTable.empty()) + return false; - CStdString strSQL = PrepareSQL("update %s set c%02u='%s' where %s=%u", - strTable.c_str(), field, strDetail.c_str(), strField.c_str(), id); - m_pDS->exec(strSQL.c_str()); + return SetSingleValue(strTable, StringUtils::Format("c%02u", dbField), strValue, strField, dbId); } catch (...) { - CLog::Log(LOGERROR, "%s failed", __FUNCTION__); + CLog::Log(LOGERROR, "%s (%s) failed", __FUNCTION__, strSQL.c_str()); + } + return false; +} + +bool CVideoDatabase::SetSingleValue(VIDEODB_CONTENT_TYPE type, int dbId, Field dbField, const std::string &strValue) +{ + MediaType mediaType = DatabaseUtils::MediaTypeFromVideoContentType(type); + if (mediaType == MediaTypeNone) + return false; + + int dbFieldIndex = DatabaseUtils::GetField(dbField, mediaType); + if (dbFieldIndex < 0) + return false; + + return SetSingleValue(type, dbId, dbFieldIndex, strValue); +} + +bool CVideoDatabase::SetSingleValue(const std::string &table, const std::string &fieldName, const std::string &strValue, + const std::string &conditionName /* = "" */, int conditionValue /* = -1 */) +{ + if (table.empty() || fieldName.empty()) + return false; + + std::string sql; + try + { + if (NULL == m_pDB.get() || NULL == m_pDS.get()) + return false; + + sql = PrepareSQL("UPDATE %s SET %s='%s'", table.c_str(), fieldName.c_str(), strValue.c_str()); + if (!conditionName.empty()) + sql += PrepareSQL(" WHERE %s=%u", conditionName.c_str(), conditionValue); + if (m_pDS->exec(sql.c_str()) == 0) + return true; } + catch (...) + { + CLog::Log(LOGERROR, "%s (%s) failed", __FUNCTION__, sql.c_str()); + } + return false; } CStdString CVideoDatabase::GetSafeFile(const CStdString &dir, const CStdString &name) const diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h index b07c78a3b8..90fa1900c4 100644 --- a/xbmc/video/VideoDatabase.h +++ b/xbmc/video/VideoDatabase.h @@ -410,6 +410,7 @@ public: bool GetPlayCounts(const CStdString &path, CFileItemList &items); void UpdateMovieTitle(int idMovie, const CStdString& strNewMovieTitle, VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES); + bool UpdateVideoSortTitle(int idDb, const CStdString& strNewSortTitle, VIDEODB_CONTENT_TYPE iType = VIDEODB_CONTENT_MOVIES); bool HasMovieInfo(const CStdString& strFilenameAndPath); bool HasTvShowInfo(const CStdString& strFilenameAndPath); @@ -449,7 +450,11 @@ public: int SetDetailsForMusicVideo(const CStdString& strFilenameAndPath, const CVideoInfoTag& details, const std::map<std::string, std::string> &artwork, int idMVideo = -1); void SetStreamDetailsForFile(const CStreamDetails& details, const CStdString &strFileNameAndPath); void SetStreamDetailsForFileId(const CStreamDetails& details, int idFile); - void SetDetail(const CStdString& strDetail, int id, int field, VIDEODB_CONTENT_TYPE type); + + bool SetSingleValue(VIDEODB_CONTENT_TYPE type, int dbId, int dbField, const std::string &strValue); + bool SetSingleValue(VIDEODB_CONTENT_TYPE type, int dbId, Field dbField, const std::string &strValue); + bool SetSingleValue(const std::string &table, const std::string &fieldName, const std::string &strValue, + const std::string &conditionName = "", int conditionValue = -1); void DeleteMovie(int idMovie, bool bKeepId = false); void DeleteMovie(const CStdString& strFilenameAndPath, bool bKeepId = false, int idMovie = -1); diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp index 2833f1813c..5c072f3bec 100644 --- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp @@ -19,6 +19,7 @@ */ #include "GUIDialogVideoInfo.h" +#include "Application.h" #include "guilib/GUIWindow.h" #include "Util.h" #include "guilib/GUIImage.h" @@ -51,6 +52,10 @@ #include "URL.h" #include "video/VideoThumbLoader.h" #include "filesystem/Directory.h" +#include "filesystem/VideoDatabaseDirectory.h" +#ifdef HAS_UPNP +#include "network/upnp/UPnP.h" +#endif using namespace std; using namespace XFILE; @@ -342,9 +347,9 @@ void CGUIDialogVideoInfo::SetMovie(const CFileItem *item) CVideoDatabase database; if(database.Open()) { - database.SetDetail(m_movieItem->GetVideoInfoTag()->m_strTrailer, - m_movieItem->GetVideoInfoTag()->m_iDbId, - VIDEODB_ID_TRAILER, VIDEODB_CONTENT_MOVIES); + database.SetSingleValue(VIDEODB_CONTENT_MOVIES, VIDEODB_ID_TRAILER, + m_movieItem->GetVideoInfoTag()->m_iDbId, + m_movieItem->GetVideoInfoTag()->m_strTrailer); database.Close(); CUtil::DeleteVideoDatabaseDirectoryCache(); } @@ -928,3 +933,437 @@ void CGUIDialogVideoInfo::AddItemPathToFileBrowserSources(VECSOURCES &sources, c sources.push_back(itemSource); } } + +int CGUIDialogVideoInfo::ManageVideoItem(const CFileItemPtr &item) +{ + if (item == NULL || !item->IsVideoDb() || !item->HasVideoInfoTag() || item->GetVideoInfoTag()->m_iDbId < 0) + return -1; + + CVideoDatabase database; + if (!database.Open()) + return -1; + + VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)item->GetVideoContentType(); + int dbId = item->GetVideoInfoTag()->m_iDbId; + + CContextButtons buttons; + buttons.Add(CONTEXT_BUTTON_EDIT, 16105); + + if (type == VIDEODB_CONTENT_MOVIES || type == VIDEODB_CONTENT_TVSHOWS) + buttons.Add(CONTEXT_BUTTON_EDIT_SORTTITLE, 16107); + + if (item->m_bIsFolder) + { + // Have both options for folders since we don't know whether all childs are watched/unwatched + buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched + buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched + } + else + { + if (item->GetOverlayImage().Equals("OverlayWatched.png")) + buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched + else + buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched + } + + if (type == VIDEODB_CONTENT_MOVIES) + { + // only show link/unlink if there are tvshows available + if (database.HasContent(VIDEODB_CONTENT_TVSHOWS)) + { + buttons.Add(CONTEXT_BUTTON_LINK_MOVIE, 20384); + if (database.IsLinkedToTvshow(dbId)) + buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE, 20385); + } + + // set or change movie set the movie belongs to + buttons.Add(CONTEXT_BUTTON_SET_MOVIESET, 20465); + } + + if (type == VIDEODB_CONTENT_EPISODES && + item->GetVideoInfoTag()->m_iBookmarkId > 0) + buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405); + + bool result = false; + int button = CGUIDialogContextMenu::ShowAndGetChoice(buttons); + if (button >= 0) + { + switch ((CONTEXT_BUTTON)button) + { + case CONTEXT_BUTTON_EDIT: + result = UpdateVideoItemTitle(item); + break; + + case CONTEXT_BUTTON_EDIT_SORTTITLE: + result = UpdateVideoItemSortTitle(item); + break; + + case CONTEXT_BUTTON_MARK_WATCHED: + result = MarkWatched(item, true); + break; + + case CONTEXT_BUTTON_MARK_UNWATCHED: + result = MarkWatched(item, false); + break; + + case CONTEXT_BUTTON_LINK_MOVIE: + result = LinkMovieToTvShow(item, false, database); + break; + + case CONTEXT_BUTTON_UNLINK_MOVIE: + result = LinkMovieToTvShow(item, true, database); + break; + + case CONTEXT_BUTTON_SET_MOVIESET: + { + CFileItemPtr selectedSet; + if (GetSetForMovie(item.get(), selectedSet)) + result = SetMovieSet(item.get(), selectedSet.get()); + break; + } + + case CONTEXT_BUTTON_UNLINK_BOOKMARK: + database.DeleteBookMarkForEpisode(*item->GetVideoInfoTag()); + result = true; + break; + + default: + result = false; + break; + } + } + + database.Close(); + + if (result) + return button; + + return -1; +} + +//Add change a title's name +bool CGUIDialogVideoInfo::UpdateVideoItemTitle(const CFileItemPtr &pItem) +{ + // dont allow update while scanning + if (g_application.IsVideoScanning()) + { + CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0); + return false; + } + + CVideoDatabase database; + if (!database.Open()) + return false; + + int iDbId = pItem->GetVideoInfoTag()->m_iDbId; + CVideoInfoTag detail; + VIDEODB_CONTENT_TYPE iType = (VIDEODB_CONTENT_TYPE)pItem->GetVideoContentType(); + if (iType == VIDEODB_CONTENT_MOVIES) + database.GetMovieInfo("", detail, iDbId); + else if (iType == VIDEODB_CONTENT_MOVIE_SETS) + database.GetSetInfo(iDbId, detail); + else if (iType == VIDEODB_CONTENT_EPISODES) + database.GetEpisodeInfo(pItem->GetPath(), detail, iDbId); + else if (iType == VIDEODB_CONTENT_TVSHOWS) + database.GetTvShowInfo(pItem->GetVideoInfoTag()->m_strFileNameAndPath, detail, iDbId); + else if (iType == VIDEODB_CONTENT_MUSICVIDEOS) + database.GetMusicVideoInfo(pItem->GetVideoInfoTag()->m_strFileNameAndPath, detail, iDbId); + + // get the new title + if (!CGUIKeyboardFactory::ShowAndGetInput(detail.m_strTitle, g_localizeStrings.Get(16105), false)) + return false; + + database.UpdateMovieTitle(iDbId, detail.m_strTitle, iType); + return true; +} + +bool CGUIDialogVideoInfo::MarkWatched(const CFileItemPtr &item, bool bMark) +{ + if (!CProfilesManager::Get().GetCurrentProfile().canWriteDatabases()) + return false; + + // dont allow update while scanning + if (g_application.IsVideoScanning()) + { + CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0); + return false; + } + + CVideoDatabase database; + if (!database.Open()) + return false; + + CFileItemList items; + if (item->m_bIsFolder) + { + CStdString strPath = item->GetPath(); + CDirectory::GetDirectory(strPath, items); + } + else + items.Add(item); + + for (int i = 0; i < items.Size(); ++i) + { + CFileItemPtr pTmpItem = items[i]; + if (pTmpItem->m_bIsFolder) + { + MarkWatched(pTmpItem, bMark); + continue; + } + + if (pTmpItem->HasVideoInfoTag() && + ((bMark && pTmpItem->GetVideoInfoTag()->m_playCount) || + (!bMark && !pTmpItem->GetVideoInfoTag()->m_playCount))) + continue; + +#ifdef HAS_UPNP + if (!URIUtils::IsUPnP(item->GetPath()) || !UPNP::CUPnP::MarkWatched(*pTmpItem, bMark)) +#endif + { + // Clear resume bookmark + if (bMark) + database.ClearBookMarksOfFile(pTmpItem->GetPath(), CBookmark::RESUME); + + database.SetPlayCount(*pTmpItem, bMark ? 1 : 0); + } + } + + database.Close(); + + return true; +} + +bool CGUIDialogVideoInfo::GetMoviesForSet(const CFileItem *setItem, CFileItemList &originalMovies, CFileItemList &selectedMovies) +{ + CVideoDatabase videodb; + if (!videodb.Open()) + return false; + + CStdString strHeading; strHeading.Format(g_localizeStrings.Get(20457)); + CStdString baseDir; + baseDir.Format("videodb://movies/sets/%d", setItem->GetVideoInfoTag()->m_iDbId); + + if (!CDirectory::GetDirectory(baseDir, originalMovies) || originalMovies.Size() <= 0) // keep a copy of the original members of the set + return false; + + CFileItemList listItems; + if (!videodb.GetSortedVideos(MediaTypeMovie, "videodb://movies", SortDescription(), listItems) || 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); + vector<int> selectedIndices; + for (int i = 0; i < originalMovies.Size(); i++) + { + for (int listIndex = 0; listIndex < listItems.Size(); listIndex++) + { + if (listItems.Get(listIndex)->GetVideoInfoTag()->m_iDbId == originalMovies[i]->GetVideoInfoTag()->m_iDbId) + { + selectedIndices.push_back(listIndex); + break; + } + } + } + dialog->SetSelected(selectedIndices); + dialog->EnableButton(true, 186); + dialog->DoModal(); + + if (dialog->IsConfirmed()) + { + selectedMovies.Copy(dialog->GetSelectedItems()); + return (selectedMovies.Size() > 0); + } + else + return false; +} + +bool CGUIDialogVideoInfo::GetSetForMovie(const CFileItem *movieItem, CFileItemPtr &selectedSet) +{ + CVideoDatabase videodb; + if (!videodb.Open()) + return false; + + CFileItemList listItems; + CStdString baseDir = "videodb://movies/sets/"; + if (!CDirectory::GetDirectory(baseDir, listItems) || listItems.Size() <= 0) + return false; + listItems.Sort(SortByLabel, SortOrderAscending, SortAttributeIgnoreArticle); + + int currentSetId = 0; + CStdString currentSetLabel; + + if (movieItem->GetVideoInfoTag()->m_iSetId > currentSetId) + { + currentSetId = movieItem->GetVideoInfoTag()->m_iSetId; + currentSetLabel = videodb.GetSetById(currentSetId); + } + + if (currentSetId > 0) + { + // add clear item + CStdString strClear; strClear.Format(g_localizeStrings.Get(20467), currentSetLabel); + CFileItemPtr clearItem(new CFileItem(strClear)); + clearItem->GetVideoInfoTag()->m_iDbId = -1; // -1 will be used to clear set + listItems.AddFront(clearItem, 0); + // add keep current set item + CStdString strKeep; strKeep.Format(g_localizeStrings.Get(20469), currentSetLabel); + CFileItemPtr keepItem(new CFileItem(strKeep)); + keepItem->GetVideoInfoTag()->m_iDbId = currentSetId; + listItems.AddFront(keepItem, 1); + } + + CGUIDialogSelect *dialog = (CGUIDialogSelect *)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); + if (dialog == NULL) + return false; + + CStdString strHeading; + strHeading.Format(g_localizeStrings.Get(20466)); + dialog->Reset(); + dialog->SetHeading(strHeading); + dialog->SetItems(&listItems); + if (currentSetId >= 0) + { + for (int listIndex = 0; listIndex < listItems.Size(); listIndex++) + { + if (listItems.Get(listIndex)->GetVideoInfoTag()->m_iDbId == currentSetId) + { + dialog->SetSelected(listIndex); + break; + } + } + } + dialog->EnableButton(true, 20468); // new set via button + dialog->DoModal(); + + if (dialog->IsButtonPressed()) + { // creating new set + CStdString newSetTitle; + if (!CGUIKeyboardFactory::ShowAndGetInput(newSetTitle, g_localizeStrings.Get(20468), false)) + return false; + int idSet = videodb.AddSet(newSetTitle); + map<string, string> movieArt, setArt; + if (!videodb.GetArtForItem(idSet, "set", setArt)) + { + videodb.GetArtForItem(movieItem->GetVideoInfoTag()->m_iDbId, "movie", movieArt); + videodb.SetArtForItem(idSet, "set", movieArt); + } + CFileItemPtr newSet(new CFileItem(newSetTitle)); + newSet->GetVideoInfoTag()->m_iDbId = idSet; + selectedSet = newSet; + return true; + } + else if (dialog->IsConfirmed()) + { + selectedSet = dialog->GetSelectedItem(); + return (selectedSet != NULL); + } + else + return false; +} + +bool CGUIDialogVideoInfo::SetMovieSet(const CFileItem *movieItem, const CFileItem *selectedSet) +{ + CVideoDatabase videodb; + if (!videodb.Open()) + return false; + + videodb.SetMovieSet(movieItem->GetVideoInfoTag()->m_iDbId, selectedSet->GetVideoInfoTag()->m_iDbId); + return true; +} + +bool CGUIDialogVideoInfo::UpdateVideoItemSortTitle(const CFileItemPtr &pItem) +{ + // dont allow update while scanning + if (g_application.IsVideoScanning()) + { + CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0); + return false; + } + + CVideoDatabase database; + if (!database.Open()) + return false; + + int iDbId = pItem->GetVideoInfoTag()->m_iDbId; + CVideoInfoTag detail; + VIDEODB_CONTENT_TYPE iType = (VIDEODB_CONTENT_TYPE)pItem->GetVideoContentType(); + if (iType == VIDEODB_CONTENT_MOVIES) + database.GetMovieInfo("", detail, iDbId); + else if (iType == VIDEODB_CONTENT_TVSHOWS) + database.GetTvShowInfo(pItem->GetVideoInfoTag()->m_strFileNameAndPath, detail, iDbId); + + // get the new sort title + if (!CGUIKeyboardFactory::ShowAndGetInput(detail.m_strTitle, g_localizeStrings.Get(16107), false)) + return false; + + return database.UpdateVideoSortTitle(iDbId, detail.m_strTitle, iType); +} + +bool CGUIDialogVideoInfo::LinkMovieToTvShow(const CFileItemPtr &item, bool bRemove, CVideoDatabase &database) +{ + int dbId = item->GetVideoInfoTag()->m_iDbId; + + CFileItemList list; + if (bRemove) + { + vector<int> ids; + if (!database.GetLinksToTvShow(dbId, ids)) + return false; + + for (unsigned int i = 0; i < ids.size(); ++i) + { + CVideoInfoTag tag; + database.GetTvShowInfo("", tag, ids[i]); + CFileItemPtr show(new CFileItem(tag)); + list.Add(show); + } + } + else + { + database.GetTvShowsNav("videodb://tvshows/titles", list); + + // remove already linked shows + vector<int> ids; + if (!database.GetLinksToTvShow(dbId, ids)) + return false; + + for (int i = 0; i < list.Size(); ) + { + size_t j; + for (j = 0; j < ids.size(); ++j) + { + if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j]) + break; + } + if (j == ids.size()) + i++; + else + list.Remove(i); + } + } + + int iSelectedLabel = 0; + if (list.Size() > 1) + { + list.Sort(SortByLabel, SortOrderAscending, CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone); + CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); + pDialog->Reset(); + pDialog->SetItems(&list); + pDialog->SetHeading(20356); + pDialog->DoModal(); + iSelectedLabel = pDialog->GetSelectedLabel(); + } + + if (iSelectedLabel > -1) + return database.LinkMovieToTvshow(dbId, list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove); + + return false; +} diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.h b/xbmc/video/dialogs/GUIDialogVideoInfo.h index bc77a4f391..2ce4aca43a 100644 --- a/xbmc/video/dialogs/GUIDialogVideoInfo.h +++ b/xbmc/video/dialogs/GUIDialogVideoInfo.h @@ -23,6 +23,8 @@ #include "guilib/GUIDialog.h" #include "FileItem.h" +class CVideoDatabase; + class CGUIDialogVideoInfo : public CGUIDialog { @@ -43,6 +45,14 @@ public: static std::string ChooseArtType(const CFileItem &item, std::map<std::string, std::string> ¤tArt); static void AddItemPathToFileBrowserSources(VECSOURCES &sources, const CFileItem &item); + + static int ManageVideoItem(const CFileItemPtr &item); + static bool UpdateVideoItemTitle(const CFileItemPtr &pItem); + static bool MarkWatched(const CFileItemPtr &item, bool bMark); + + 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); protected: virtual void OnInitWindow(); void Update(); @@ -58,6 +68,9 @@ protected: void OnGetFanart(); void PlayTrailer(); + static bool UpdateVideoItemSortTitle(const CFileItemPtr &pItem); + static bool LinkMovieToTvShow(const CFileItemPtr &item, bool bRemove, CVideoDatabase &database); + CFileItemPtr m_movieItem; CFileItemList *m_castList; bool m_bViewReview; diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp index 51bd14eafb..6fec4f48c5 100644 --- a/xbmc/video/windows/GUIWindowVideoBase.cpp +++ b/xbmc/video/windows/GUIWindowVideoBase.cpp @@ -92,8 +92,6 @@ using namespace PVR; #define CONTROL_LABELFILES 12 #define CONTROL_PLAY_DVD 6 -#define CONTROL_STACK 7 -#define CONTROL_BTNSCAN 8 #define PROPERTY_GROUP_BY "group.by" #define PROPERTY_GROUP_MIXED "group.mixed" @@ -156,21 +154,15 @@ bool CGUIWindowVideoBase::OnMessage(CGUIMessage& message) case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); - if (iControl == CONTROL_STACK) - { - CSettings::Get().ToggleBool("myvideos.stackvideos"); - CSettings::Get().Save(); - UpdateButtons(); - Update( m_vecItems->GetPath() ); - } #if defined(HAS_DVD_DRIVE) - else if (iControl == CONTROL_PLAY_DVD) + if (iControl == CONTROL_PLAY_DVD) { // play movie... MEDIA_DETECT::CAutorun::PlayDiscAskResume(g_mediaManager.TranslateDevicePath("")); } + else #endif - else if (iControl == CONTROL_BTNTYPE) + if (iControl == CONTROL_BTNTYPE) { CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_BTNTYPE); g_windowManager.SendMessage(msg); @@ -269,12 +261,6 @@ void CGUIWindowVideoBase::UpdateButtons() // Select the current window as default item int nWindow = CSettings::Get().GetInt("myvideos.startwindow")-WINDOW_VIDEO_FILES; CONTROL_SELECT_ITEM(CONTROL_BTNTYPE, nWindow); - - CONTROL_ENABLE(CONTROL_BTNSCAN); - - SET_CONTROL_LABEL(CONTROL_STACK, 14000); // Stack - SET_CONTROL_SELECTED(GetID(), CONTROL_STACK, CSettings::Get().GetBool("myvideos.stackvideos")); - CONTROL_ENABLE_ON_CONDITION(CONTROL_STACK, m_stackingAvailable); CGUIMediaWindow::UpdateButtons(); } @@ -1274,12 +1260,6 @@ void CGUIWindowVideoBase::GetContextButtons(int itemNumber, CContextButtons &but CGUIMediaWindow::GetContextButtons(itemNumber, buttons); } -void CGUIWindowVideoBase::GetNonContextButtons(int itemNumber, CContextButtons &buttons) -{ - if (g_playlistPlayer.GetPlaylist(PLAYLIST_VIDEO).size() > 0) - buttons.Add(CONTEXT_BUTTON_NOW_PLAYING, 13350); -} - bool CGUIWindowVideoBase::OnPlayStackPart(int iItem) { if (iItem < 0 || iItem >= m_vecItems->Size()) @@ -1397,21 +1377,11 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) case CONTEXT_BUTTON_RESUME_ITEM: return OnFileAction(itemNumber, SELECT_ACTION_RESUME); - case CONTEXT_BUTTON_NOW_PLAYING: - g_windowManager.ActivateWindow(WINDOW_VIDEO_PLAYLIST); - return true; - case CONTEXT_BUTTON_INFO: OnInfo(itemNumber); return true; - case CONTEXT_BUTTON_STOP_SCANNING: - { - g_application.StopVideoScan(); - return true; - } case CONTEXT_BUTTON_SCAN: - case CONTEXT_BUTTON_UPDATE_TVSHOW: { if( !item) return false; @@ -1454,7 +1424,7 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) case CONTEXT_BUTTON_MARK_WATCHED: { int newSelection = m_viewControl.GetSelectedItem() + 1; - MarkWatched(item,true); + CGUIDialogVideoInfo::MarkWatched(item, true); m_viewControl.SetSelectedItem(newSelection); CUtil::DeleteVideoDatabaseDirectoryCache(); @@ -1462,7 +1432,7 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) return true; } case CONTEXT_BUTTON_MARK_UNWATCHED: - MarkWatched(item,false); + CGUIDialogVideoInfo::MarkWatched(item, false); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; @@ -1637,110 +1607,6 @@ void CGUIWindowVideoBase::OnDeleteItem(CFileItemPtr item) CFileUtils::DeleteItem(item); } -void CGUIWindowVideoBase::MarkWatched(const CFileItemPtr &item, bool bMark) -{ - if (!CProfilesManager::Get().GetCurrentProfile().canWriteDatabases()) - return; - // dont allow update while scanning - if (g_application.IsVideoScanning()) - { - CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0); - return; - } - - CVideoDatabase database; - if (database.Open()) - { - CFileItemList items; - if (item->m_bIsFolder) - { - CStdString strPath = item->GetPath(); - CDirectory::GetDirectory(strPath, items); - } - else - items.Add(item); - - for (int i=0;i<items.Size();++i) - { - CFileItemPtr pItem=items[i]; - if (pItem->m_bIsFolder) - { - MarkWatched(pItem, bMark); - continue; - } - - if (pItem->HasVideoInfoTag() && - (( bMark && pItem->GetVideoInfoTag()->m_playCount) || - (!bMark && !(pItem->GetVideoInfoTag()->m_playCount)))) - continue; - -#ifdef HAS_UPNP - if (!URIUtils::IsUPnP(item->GetPath()) || !UPNP::CUPnP::MarkWatched(*pItem, bMark)) -#endif - { - // Clear resume bookmark - if (bMark) - database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME); - - database.SetPlayCount(*pItem, bMark ? 1 : 0); - } - } - - database.Close(); - } -} - -//Add change a title's name -void CGUIWindowVideoBase::UpdateVideoTitle(const CFileItem* pItem) -{ - // dont allow update while scanning - if (g_application.IsVideoScanning()) - { - CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0); - return; - } - - CVideoInfoTag detail; - CVideoDatabase database; - database.Open(); - CVideoDatabaseDirectory dir; - CQueryParams params; - dir.GetQueryParams(pItem->GetPath(),params); - int iDbId = pItem->GetVideoInfoTag()->m_iDbId; - - VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES; - if (pItem->HasVideoInfoTag() && (!pItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty() || - pItem->GetVideoInfoTag()->m_iEpisode > 0)) - { - 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; - if (params.GetSetId() != -1 && params.GetMovieId() == -1) - iType = VIDEODB_CONTENT_MOVIE_SETS; - if (iType == VIDEODB_CONTENT_MOVIES) - database.GetMovieInfo("", detail, pItem->GetVideoInfoTag()->m_iDbId); - if (iType == VIDEODB_CONTENT_MOVIE_SETS) - database.GetSetInfo(params.GetSetId(), detail); - if (iType == VIDEODB_CONTENT_EPISODES) - database.GetEpisodeInfo(pItem->GetPath(),detail,pItem->GetVideoInfoTag()->m_iDbId); - if (iType == VIDEODB_CONTENT_TVSHOWS) - database.GetTvShowInfo(pItem->GetVideoInfoTag()->m_strFileNameAndPath,detail,pItem->GetVideoInfoTag()->m_iDbId); - if (iType == VIDEODB_CONTENT_MUSICVIDEOS) - database.GetMusicVideoInfo(pItem->GetVideoInfoTag()->m_strFileNameAndPath,detail,pItem->GetVideoInfoTag()->m_iDbId); - - CStdString strInput; - strInput = detail.m_strTitle; - - //Get the new title - if (!CGUIKeyboardFactory::ShowAndGetInput(strInput, g_localizeStrings.Get(16105), false)) - return; - - database.UpdateMovieTitle(iDbId, strInput, iType); -} - void CGUIWindowVideoBase::LoadPlayList(const CStdString& strPlayList, int iPlayList /* = PLAYLIST_VIDEO */) { // if partymode is active, we disable it diff --git a/xbmc/video/windows/GUIWindowVideoBase.h b/xbmc/video/windows/GUIWindowVideoBase.h index c483b263ba..1559934cd6 100644 --- a/xbmc/video/windows/GUIWindowVideoBase.h +++ b/xbmc/video/windows/GUIWindowVideoBase.h @@ -50,8 +50,6 @@ public: void AddToDatabase(int iItem); virtual void OnInfo(CFileItem* pItem, const ADDON::ScraperPtr& scraper); - static void MarkWatched(const CFileItemPtr &pItem, bool bMark); - static void UpdateVideoTitle(const CFileItem* pItem); /*! \brief Show dialog allowing selection of wanted playback item */ static bool ShowPlaySelection(CFileItemPtr& item); @@ -104,7 +102,6 @@ protected: virtual bool CanContainFilter(const CStdString &strDirectory) const; virtual void GetContextButtons(int itemNumber, CContextButtons &buttons); - void GetNonContextButtons(int itemNumber, CContextButtons &buttons); virtual bool OnContextButton(int itemNumber, CONTEXT_BUTTON button); virtual void OnQueueItem(int iItem); virtual void OnDeleteItem(CFileItemPtr pItem); diff --git a/xbmc/video/windows/GUIWindowVideoNav.cpp b/xbmc/video/windows/GUIWindowVideoNav.cpp index 105270c452..73e349b88e 100644 --- a/xbmc/video/windows/GUIWindowVideoNav.cpp +++ b/xbmc/video/windows/GUIWindowVideoNav.cpp @@ -77,9 +77,10 @@ using namespace std; #define CONTROL_FILTER 15 #define CONTROL_BTNPARTYMODE 16 -#define CONTROL_BTNFLATTEN 17 #define CONTROL_LABELEMPTY 18 +#define CONTROL_UPDATE_LIBRARY 20 + CGUIWindowVideoNav::CGUIWindowVideoNav(void) : CGUIWindowVideoBase(WINDOW_VIDEO_NAV, "MyVideoNav.xml") { @@ -169,16 +170,6 @@ bool CGUIWindowVideoNav::OnMessage(CGUIMessage& message) OnFilterItems(GetProperty("filter").asString()); return true; } - else if (iControl == CONTROL_BTNFLATTEN) - { - CSettings::Get().ToggleBool("myvideos.flatten"); - CSettings::Get().Save(); - SetProperty("flattened", CSettings::Get().GetBool("myvideos.flatten")); - CUtil::DeleteVideoDatabaseDirectoryCache(); - SetupShares(); - Update(""); - return true; - } else if (iControl == CONTROL_BTNSHOWALL) { if (CMediaSettings::Get().GetWatchedMode(m_vecItems->GetContent()) == WatchedModeAll) @@ -189,6 +180,14 @@ bool CGUIWindowVideoNav::OnMessage(CGUIMessage& message) OnFilterItems(GetProperty("filter").asString()); return true; } + else if (iControl == CONTROL_UPDATE_LIBRARY) + { + if (!g_application.IsVideoScanning()) + OnScan(""); + else + g_application.StopVideoScan(); + return true; + } } break; // update the display @@ -542,7 +541,7 @@ void CGUIWindowVideoNav::UpdateButtons() SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled()); - SET_CONTROL_SELECTED(GetID(),CONTROL_BTNFLATTEN, CSettings::Get().GetBool("myvideos.flatten")); + CONTROL_ENABLE_ON_CONDITION(CONTROL_UPDATE_LIBRARY, !m_vecItems->IsAddonsPath() && !m_vecItems->IsPlugin() && !m_vecItems->IsScript()); } bool CGUIWindowVideoNav::GetFilteredItems(const CStdString &filter, CFileItemList &items) @@ -857,10 +856,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt if (!item) { - if (g_application.IsVideoScanning()) - buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); - else - buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653); + // nothing to do here } else if (m_vecItems->GetPath().Equals("sources://video/")) { @@ -945,12 +941,17 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt if (g_application.IsVideoScanning()) buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); else - buttons.Add(CONTEXT_BUTTON_UPDATE_TVSHOW, 13349); + buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } - if (!item->IsPlugin() && !item->IsScript() && !item->IsLiveTV() && !item->IsAddonsPath() && - item->GetPath() != "sources://video/" && item->GetPath() != "special://videoplaylists/" && - item->GetPath().Left(19) != "newsmartplaylist://" && item->GetPath().Left(14) != "newplaylist://" && - item->GetPath().Left(9) != "newtag://") + if (!g_application.IsVideoScanning() && item->IsVideoDb() && item->HasVideoInfoTag() && + (!item->m_bIsFolder || m_vecItems->GetContent().Equals("movies") || m_vecItems->GetContent().Equals("tvshows"))) + { + buttons.Add(CONTEXT_BUTTON_EDIT, 16106); + } + else if (!item->IsPlugin() && !item->IsScript() && !item->IsLiveTV() && !item->IsAddonsPath() && + item->GetPath() != "sources://video/" && item->GetPath() != "special://videoplaylists/" && + item->GetPath().Left(19) != "newsmartplaylist://" && item->GetPath().Left(14) != "newplaylist://" && + item->GetPath().Left(9) != "newtag://") { if (item->m_bIsFolder) { @@ -966,30 +967,12 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched } } - if ((node == NODE_TYPE_TITLE_TVSHOWS) || - (item->IsVideoDb() && item->HasVideoInfoTag() && !item->m_bIsFolder)) - { - buttons.Add(CONTEXT_BUTTON_EDIT, 16105); //Edit Title - } - if (m_database.HasContent(VIDEODB_CONTENT_TVSHOWS) && item->HasVideoInfoTag() && - !item->m_bIsFolder && item->GetVideoInfoTag()->m_iEpisode == -1 && - item->GetVideoInfoTag()->m_artist.empty() && item->GetVideoInfoTag()->m_iDbId >= 0) // movie entry - { - if (m_database.IsLinkedToTvshow(item->GetVideoInfoTag()->m_iDbId)) - buttons.Add(CONTEXT_BUTTON_UNLINK_MOVIE,20385); - buttons.Add(CONTEXT_BUTTON_LINK_MOVIE,20384); - } - if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_type == "movie") // movie entry - { - buttons.Add(CONTEXT_BUTTON_SET_MOVIESET,20465); // set or change movie set the movie belongs to - } if (node == NODE_TYPE_SEASONS && item->m_bIsFolder) buttons.Add(CONTEXT_BUTTON_SET_SEASON_ART, 13511); if (StringUtils::StartsWith(item->GetPath(), "videodb://movies/sets/") && item->GetPath().size() > 22 && item->m_bIsFolder) // sets { - buttons.Add(CONTEXT_BUTTON_EDIT, 16105); buttons.Add(CONTEXT_BUTTON_SET_MOVIESET_ART, 13511); buttons.Add(CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS, 20465); buttons.Add(CONTEXT_BUTTON_DELETE, 646); @@ -1019,29 +1002,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt } if (item->IsVideoDb() && item->HasVideoInfoTag() && (!item->m_bIsFolder || node == NODE_TYPE_TITLE_TVSHOWS)) - { - if (info && info->Content() == CONTENT_TVSHOWS) - { - if(item->GetVideoInfoTag()->m_iBookmarkId != -1 && - item->GetVideoInfoTag()->m_iBookmarkId != 0) - { - buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405); - } - } buttons.Add(CONTEXT_BUTTON_DELETE, 646); - } - - // this should ideally be non-contextual (though we need some context for non-tv show node I guess) - if (g_application.IsVideoScanning()) - { - if (node != NODE_TYPE_TITLE_TVSHOWS) - buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); - } - else - { - if (!(item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin())) - buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653); - } } if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot()) @@ -1055,7 +1016,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt buttons.Add(CONTEXT_BUTTON_RENAME, 118); } // add "Set/Change content" to folders - if (item->m_bIsFolder && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath())) + if (item->m_bIsFolder && !item->IsVideoDb() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath())) { if (!g_application.IsVideoScanning()) { @@ -1073,7 +1034,6 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045); } } - CGUIWindowVideoBase::GetNonContextButtons(itemNumber, buttons); } // predicate used by sorting and set_difference @@ -1101,10 +1061,17 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) switch (button) { case CONTEXT_BUTTON_EDIT: - UpdateVideoTitle(item.get()); - CUtil::DeleteVideoDatabaseDirectoryCache(); - Refresh(); - return true; + { + CONTEXT_BUTTON ret = (CONTEXT_BUTTON)CGUIDialogVideoInfo::ManageVideoItem(item); + if (ret >= 0) + { + if (ret == CONTEXT_BUTTON_MARK_WATCHED) + m_viewControl.SetSelectedItem(itemNumber + 1); + + Refresh(true); + } + return true; + } case CONTEXT_BUTTON_SET_SEASON_ART: case CONTEXT_BUTTON_SET_ACTOR_THUMB: @@ -1329,23 +1296,12 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) items.RemoveDiscCache(GetID()); return true; } - case CONTEXT_BUTTON_SET_MOVIESET: - { - CFileItemPtr selectedSet; - if (!GetSetForMovie(item, selectedSet)) - return true; - - if (SetMovieSet(item, selectedSet)) - Refresh(); - - return true; - } case CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS: { CFileItemList originalItems; CFileItemList selectedItems; - if (!GetMoviesForSet(item, originalItems, selectedItems) || selectedItems.Size() == 0) // need at least one item selected + 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); @@ -1358,7 +1314,7 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) 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 (SetMovieSet(*it, item)) + if (CGUIDialogVideoInfo::SetMovieSet(it->get(), item.get())) refreshNeeded = true; } // update the "deleted" items @@ -1368,7 +1324,7 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) 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, clearItem)) + if (CGUIDialogVideoInfo::SetMovieSet(it->get(), clearItem.get())) refreshNeeded = true; } @@ -1377,22 +1333,6 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) Refresh(); return true; } - case CONTEXT_BUTTON_UPDATE_LIBRARY: - { - OnScan(""); - return true; - } - case CONTEXT_BUTTON_UNLINK_MOVIE: - { - OnLinkMovieToTvShow(itemNumber, true); - Refresh(); - return true; - } - case CONTEXT_BUTTON_LINK_MOVIE: - { - OnLinkMovieToTvShow(itemNumber, false); - return true; - } case CONTEXT_BUTTON_GO_TO_ARTIST: { CStdString strPath; @@ -1425,16 +1365,6 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) return true; } - case CONTEXT_BUTTON_UNLINK_BOOKMARK: - { - m_database.Open(); - m_database.DeleteBookMarkForEpisode(*m_vecItems->Get(itemNumber)->GetVideoInfoTag()); - m_database.Close(); - CUtil::DeleteVideoDatabaseDirectoryCache(); - Refresh(); - return true; - } - default: break; @@ -1497,63 +1427,6 @@ void CGUIWindowVideoNav::OnChooseFanart(const CFileItem &videoItem) Refresh(); } -void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove) -{ - CFileItemList list; - if (bRemove) - { - vector<int> ids; - if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids)) - return; - for (unsigned int i=0;i<ids.size();++i) - { - CVideoInfoTag tag; - m_database.GetTvShowInfo("",tag,ids[i]); - CFileItemPtr show(new CFileItem(tag)); - list.Add(show); - } - } - else - { - m_database.GetTvShowsNav("videodb://tvshows/titles",list); - - // remove already linked shows - vector<int> ids; - if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids)) - return; - for (int i=0;i<list.Size();) - { - unsigned int j; - for (j=0;j<ids.size();++j) - { - if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j]) - break; - } - if (j == ids.size()) - i++; - else - list.Remove(i); - } - } - int iSelectedLabel = 0; - if (list.Size() > 1) - { - list.Sort(SortByLabel, SortOrderAscending, CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone); - CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); - pDialog->Reset(); - pDialog->SetItems(&list); - pDialog->SetHeading(20356); - pDialog->DoModal(); - iSelectedLabel = pDialog->GetSelectedLabel(); - } - if (iSelectedLabel > -1) - { - m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId, - list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove); - CUtil::DeleteVideoDatabaseDirectoryCache(); - } -} - bool CGUIWindowVideoNav::OnClick(int iItem) { CFileItemPtr item = m_vecItems->Get(iItem); @@ -1708,7 +1581,7 @@ bool CGUIWindowVideoNav::ApplyWatchedFilter(CFileItemList &items) if (!items.IsVideoDb()) filterWatched = true; if (items.GetContent() == "tvshows" && - (items.IsSmartPlayList() || (items.HasProperty("library.filter") && items.GetProperty("library.filter").asBoolean()))) + (items.IsSmartPlayList() || items.IsLibraryFolder())) node = NODE_TYPE_TITLE_TVSHOWS; // so that the check below works int watchMode = CMediaSettings::Get().GetWatchedMode(m_vecItems->GetContent()); @@ -1815,152 +1688,6 @@ bool CGUIWindowVideoNav::GetItemsForTag(const CStdString &strHeading, const std: return items.Size() > 0; } -bool CGUIWindowVideoNav::GetMoviesForSet(CFileItemPtr &setItem, CFileItemList &originalMovies, CFileItemList &selectedMovies) -{ - CVideoDatabase videodb; - if (!videodb.Open()) - return false; - - CStdString strHeading; strHeading.Format(g_localizeStrings.Get(20457)); - CStdString baseDir; - baseDir.Format("videodb://movies/sets/%d", setItem->GetVideoInfoTag()->m_iDbId); - - if (!CDirectory::GetDirectory(baseDir, originalMovies) || originalMovies.Size() <= 0) // keep a copy of the original members of the set - return false; - - CFileItemList listItems; - if (!videodb.GetSortedVideos(MediaTypeMovie, "videodb://movies", SortDescription(), listItems) || 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); - vector<int> selectedIndices; - for (int i = 0; i < originalMovies.Size(); i++) - { - for (int listIndex = 0; listIndex < listItems.Size(); listIndex++) - { - if (listItems.Get(listIndex)->GetVideoInfoTag()->m_iDbId == originalMovies[i]->GetVideoInfoTag()->m_iDbId) - { - selectedIndices.push_back(listIndex); - break; - } - } - } - dialog->SetSelected(selectedIndices); - dialog->EnableButton(true, 186); - dialog->DoModal(); - - if (dialog->IsConfirmed()) - { - selectedMovies.Copy(dialog->GetSelectedItems()); - return (selectedMovies.Size() > 0); - } - else - return false; -} - -bool CGUIWindowVideoNav::GetSetForMovie(CFileItemPtr &movieItem, CFileItemPtr &selectedSet) -{ - CVideoDatabase videodb; - if (!videodb.Open()) - return false; - - CFileItemList listItems; - CStdString baseDir = "videodb://movies/sets/"; - if (!CDirectory::GetDirectory(baseDir, listItems) || listItems.Size() <= 0) - return false; - listItems.Sort(SortByLabel, SortOrderAscending, SortAttributeIgnoreArticle); - - int currentSetId = 0; - CStdString currentSetLabel; - - if (movieItem->GetVideoInfoTag()->m_iSetId > currentSetId) - { - currentSetId = movieItem->GetVideoInfoTag()->m_iSetId; - currentSetLabel = videodb.GetSetById(currentSetId); - } - - if (currentSetId > 0) - { - // add clear item - CStdString strClear; strClear.Format(g_localizeStrings.Get(20467), currentSetLabel); - CFileItemPtr clearItem(new CFileItem(strClear)); - clearItem->GetVideoInfoTag()->m_iDbId = -1; // -1 will be used to clear set - listItems.AddFront(clearItem, 0); - // add keep current set item - CStdString strKeep; strKeep.Format(g_localizeStrings.Get(20469), currentSetLabel); - CFileItemPtr keepItem(new CFileItem(strKeep)); - keepItem->GetVideoInfoTag()->m_iDbId = currentSetId; - listItems.AddFront(keepItem, 1); - } - - CGUIDialogSelect *dialog = (CGUIDialogSelect *)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); - if (dialog == NULL) - return false; - - CStdString strHeading; - strHeading.Format(g_localizeStrings.Get(20466)); - dialog->Reset(); - dialog->SetHeading(strHeading); - dialog->SetItems(&listItems); - if (currentSetId >= 0) - { - for (int listIndex = 0; listIndex < listItems.Size(); listIndex++) - { - if (listItems.Get(listIndex)->GetVideoInfoTag()->m_iDbId == currentSetId) - { - dialog->SetSelected(listIndex); - break; - } - } - } - dialog->EnableButton(true, 20468); // new set via button - dialog->DoModal(); - - if (dialog->IsButtonPressed()) - { // creating new set - CStdString newSetTitle; - if (!CGUIKeyboardFactory::ShowAndGetInput(newSetTitle, g_localizeStrings.Get(20468), false)) - return false; - int idSet = videodb.AddSet(newSetTitle); - map<string, string> movieArt, setArt; - if (!videodb.GetArtForItem(idSet, "set", setArt)) - { - videodb.GetArtForItem(movieItem->GetVideoInfoTag()->m_iDbId, "movie", movieArt); - videodb.SetArtForItem(idSet, "set", movieArt); - } - CFileItemPtr newSet(new CFileItem(newSetTitle)); - newSet->GetVideoInfoTag()->m_iDbId = idSet; - selectedSet = newSet; - return true; - } - else if (dialog->IsConfirmed()) - { - selectedSet = dialog->GetSelectedItem(); - return (selectedSet != NULL); - } - else - return false; -} - -bool CGUIWindowVideoNav::SetMovieSet(CFileItemPtr &movieItem, CFileItemPtr &selectedSet) -{ - CVideoDatabase videodb; - if (!videodb.Open()) - return false; - - videodb.SetMovieSet(movieItem->GetVideoInfoTag()->m_iDbId, selectedSet->GetVideoInfoTag()->m_iDbId); - return true; -} - CStdString CGUIWindowVideoNav::GetLocalizedType(const std::string &strType) { if (strType == "movie" || strType == "movies") diff --git a/xbmc/video/windows/GUIWindowVideoNav.h b/xbmc/video/windows/GUIWindowVideoNav.h index a7ae9e0289..d36bb0c355 100644 --- a/xbmc/video/windows/GUIWindowVideoNav.h +++ b/xbmc/video/windows/GUIWindowVideoNav.h @@ -64,7 +64,6 @@ protected: virtual bool GetFilteredItems(const CStdString &filter, CFileItemList &items); virtual void OnItemLoaded(CFileItem* pItem) {}; - void OnLinkMovieToTvShow(int itemnumber, bool bRemove); // override base class methods virtual bool GetDirectory(const CStdString &strDirectory, CFileItemList &items); virtual void UpdateButtons(); @@ -81,9 +80,5 @@ protected: bool GetItemsForTag(const CStdString &strHeading, const std::string &type, CFileItemList &items, int idTag = -1, bool showAll = true); static CStdString GetLocalizedType(const std::string &strType); - bool GetSetForMovie(CFileItemPtr &movieItem, CFileItemPtr &selectedSet); - bool GetMoviesForSet(CFileItemPtr &setItem, CFileItemList &originalMovies, CFileItemList &selectedMovies); - bool SetMovieSet(CFileItemPtr &movieItem, CFileItemPtr &selectedSet); - VECSOURCES m_shares; }; diff --git a/xbmc/view/GUIViewState.cpp b/xbmc/view/GUIViewState.cpp index 95c8a9a057..e2f8677b14 100644 --- a/xbmc/view/GUIViewState.cpp +++ b/xbmc/view/GUIViewState.cpp @@ -82,7 +82,7 @@ CGUIViewState* CGUIViewState::GetViewState(int windowId, const CFileItemList& it return new CGUIViewStateMusicSearch(items); if (items.IsSmartPlayList() || url.GetProtocol() == "upnp" || - items.GetProperty("library.filter").asBoolean()) + items.IsLibraryFolder()) { if (items.GetContent() == "songs" || items.GetContent() == "albums" || |