aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/resource.language.en_gb/resources/strings.po4
-rw-r--r--cmake/scripts/android/Install.cmake1
-rw-r--r--system/shaders/GLES/2.0/gles_shader_clip.vert39
-rw-r--r--system/shaders/GLES/2.0/gles_shader_simple.vert26
-rw-r--r--tools/Linux/kodi.sh.in7
-rw-r--r--tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in63
-rw-r--r--tools/android/packaging/xbmc/src/XBMCTextureCache.java.in32
-rw-r--r--xbmc/AutoSwitch.cpp1
-rw-r--r--xbmc/Autorun.cpp1
-rw-r--r--xbmc/BackgroundInfoLoader.cpp1
-rw-r--r--xbmc/CMakeLists.txt2
-rw-r--r--xbmc/CueDocument.cpp1
-rw-r--r--xbmc/FileItem.cpp1169
-rw-r--r--xbmc/FileItem.h182
-rw-r--r--xbmc/FileItemList.cpp1174
-rw-r--r--xbmc/FileItemList.h206
-rw-r--r--xbmc/GUIInfoManager.cpp10
-rw-r--r--xbmc/NfoFile.cpp1
-rw-r--r--xbmc/PartyModeManager.cpp1
-rw-r--r--xbmc/PlayListPlayer.cpp12
-rw-r--r--xbmc/PlayListPlayer.h7
-rw-r--r--xbmc/URL.cpp12
-rw-r--r--xbmc/addons/AddonManager.cpp1
-rw-r--r--xbmc/addons/AddonManager.h3
-rw-r--r--xbmc/addons/AddonRepos.cpp97
-rw-r--r--xbmc/addons/AddonRepos.h10
-rw-r--r--xbmc/addons/FilesystemInstaller.cpp1
-rw-r--r--xbmc/addons/Scraper.cpp1
-rw-r--r--xbmc/addons/Skin.cpp1
-rw-r--r--xbmc/addons/VFSEntry.h1
-rw-r--r--xbmc/addons/addoninfo/AddonInfo.cpp1
-rw-r--r--xbmc/addons/gui/GUIDialogAddonInfo.cpp1
-rw-r--r--xbmc/addons/gui/GUIDialogAddonSettings.cpp1
-rw-r--r--xbmc/addons/gui/GUIViewStateAddonBrowser.cpp1
-rw-r--r--xbmc/addons/gui/GUIWindowAddonBrowser.cpp1
-rw-r--r--xbmc/addons/interfaces/Filesystem.cpp1
-rw-r--r--xbmc/addons/interfaces/gui/Window.cpp1
-rw-r--r--xbmc/addons/settings/AddonSettings.cpp1
-rw-r--r--xbmc/application/AppParamParser.cpp1
-rw-r--r--xbmc/application/AppParams.cpp4
-rw-r--r--xbmc/application/AppParams.h2
-rw-r--r--xbmc/application/Application.cpp9
-rw-r--r--xbmc/application/Application.h5
-rw-r--r--xbmc/application/ApplicationSkinHandling.cpp1
-rw-r--r--xbmc/application/ApplicationStackHelper.cpp1
-rw-r--r--xbmc/cdrip/CDDARipper.cpp1
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp4
-rw-r--r--xbmc/cores/DllLoader/exports/emu_msvcrt.cpp1
-rw-r--r--xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/DVDFileInfo.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp5
-rw-r--r--xbmc/dialogs/GUIDialogColorPicker.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogContextMenu.h1
-rw-r--r--xbmc/dialogs/GUIDialogFileBrowser.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogMediaFilter.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogMediaSource.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogSelect.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogSimpleMenu.cpp18
-rw-r--r--xbmc/dialogs/GUIDialogSimpleMenu.h2
-rw-r--r--xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp1
-rw-r--r--xbmc/events/windows/GUIViewStateEventLog.cpp1
-rw-r--r--xbmc/events/windows/GUIWindowEventLog.cpp1
-rw-r--r--xbmc/favourites/FavouritesService.h1
-rw-r--r--xbmc/favourites/GUIViewStateFavourites.cpp2
-rw-r--r--xbmc/filesystem/AddonsDirectory.cpp39
-rw-r--r--xbmc/filesystem/AudioBookFileDirectory.cpp1
-rw-r--r--xbmc/filesystem/BlurayCallback.cpp1
-rw-r--r--xbmc/filesystem/BlurayDirectory.cpp1
-rw-r--r--xbmc/filesystem/CDDADirectory.cpp1
-rw-r--r--xbmc/filesystem/DAVDirectory.cpp1
-rw-r--r--xbmc/filesystem/Directorization.h1
-rw-r--r--xbmc/filesystem/Directory.cpp1
-rw-r--r--xbmc/filesystem/DirectoryCache.cpp1
-rw-r--r--xbmc/filesystem/EventsDirectory.cpp1
-rw-r--r--xbmc/filesystem/FTPDirectory.cpp1
-rw-r--r--xbmc/filesystem/HTTPDirectory.cpp1
-rw-r--r--xbmc/filesystem/ISO9660Directory.cpp1
-rw-r--r--xbmc/filesystem/LibraryDirectory.cpp1
-rw-r--r--xbmc/filesystem/MultiPathDirectory.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp1
-rw-r--r--xbmc/filesystem/MusicFileDirectory.cpp1
-rw-r--r--xbmc/filesystem/MusicSearchDirectory.cpp1
-rw-r--r--xbmc/filesystem/NFSDirectory.cpp1
-rw-r--r--xbmc/filesystem/PlaylistDirectory.cpp1
-rw-r--r--xbmc/filesystem/PlaylistFileDirectory.cpp1
-rw-r--r--xbmc/filesystem/PluginDirectory.cpp1
-rw-r--r--xbmc/filesystem/RSSDirectory.cpp1
-rw-r--r--xbmc/filesystem/ResourceDirectory.cpp1
-rw-r--r--xbmc/filesystem/SmartPlaylistDirectory.cpp1
-rw-r--r--xbmc/filesystem/SourcesDirectory.cpp1
-rw-r--r--xbmc/filesystem/SpecialProtocolDirectory.cpp1
-rw-r--r--xbmc/filesystem/StackDirectory.cpp1
-rw-r--r--xbmc/filesystem/UDFDirectory.cpp1
-rw-r--r--xbmc/filesystem/UPnPDirectory.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp1
-rw-r--r--xbmc/filesystem/VirtualDirectory.cpp1
-rw-r--r--xbmc/filesystem/ZeroconfDirectory.cpp1
-rw-r--r--xbmc/filesystem/test/TestDirectory.cpp1
-rw-r--r--xbmc/filesystem/test/TestHTTPDirectory.cpp1
-rw-r--r--xbmc/filesystem/test/TestZipFile.cpp1
-rw-r--r--xbmc/games/addons/GameClientProperties.cpp1
-rw-r--r--xbmc/games/agents/windows/GUIAgentControllerList.cpp1
-rw-r--r--xbmc/games/controllers/dialogs/ControllerInstaller.cpp1
-rw-r--r--xbmc/games/controllers/dialogs/ControllerSelect.cpp1
-rw-r--r--xbmc/games/dialogs/GUIDialogSelectGameClient.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameSaves.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameStretchMode.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameVideoFilter.h1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogInGameSaves.h1
-rw-r--r--xbmc/games/ports/guicontrols/GUIActivePortList.cpp1
-rw-r--r--xbmc/games/ports/windows/GUIPortList.cpp1
-rw-r--r--xbmc/games/windows/GUIViewStateWindowGames.cpp1
-rw-r--r--xbmc/games/windows/GUIWindowGames.cpp1
-rw-r--r--xbmc/guilib/GUIBaseContainer.cpp1
-rw-r--r--xbmc/guilib/GUIFontManager.cpp1
-rw-r--r--xbmc/guilib/GUIFontTTF.cpp42
-rw-r--r--xbmc/guilib/GUIFontTTFGLES.cpp102
-rw-r--r--xbmc/guilib/GUIFontTTFGLES.h1
-rw-r--r--xbmc/guilib/GUIMultiImage.cpp1
-rw-r--r--xbmc/guilib/guiinfo/GUIInfoLabels.h3
-rw-r--r--xbmc/guilib/guiinfo/LibraryGUIInfo.cpp1
-rw-r--r--xbmc/guilib/guiinfo/SystemGUIInfo.cpp8
-rw-r--r--xbmc/input/keyboard/KeyboardLayoutManager.cpp1
-rw-r--r--xbmc/input/keymaps/ButtonTranslator.cpp1
-rw-r--r--xbmc/interfaces/builtins/PlayerBuiltins.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/AddonsOperations.cpp10
-rw-r--r--xbmc/interfaces/json-rpc/AddonsOperations.h3
-rw-r--r--xbmc/interfaces/json-rpc/AudioLibrary.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/FileItemHandler.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/FileOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/PVROperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/PlayerOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/PlaylistOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/ProfilesOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/TextureOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/VideoLibrary.cpp1
-rw-r--r--xbmc/interfaces/legacy/Control.cpp1
-rw-r--r--xbmc/interfaces/legacy/Dialog.cpp1
-rw-r--r--xbmc/interfaces/legacy/ModuleXbmcplugin.cpp1
-rw-r--r--xbmc/interfaces/legacy/ModuleXbmcvfs.cpp1
-rw-r--r--xbmc/interfaces/legacy/PlayList.cpp1
-rw-r--r--xbmc/interfaces/legacy/Player.cpp1
-rw-r--r--xbmc/interfaces/legacy/WindowXML.cpp1
-rw-r--r--xbmc/music/GUIViewStateMusic.cpp1
-rw-r--r--xbmc/music/MusicDatabase.cpp1
-rw-r--r--xbmc/music/MusicInfoLoader.cpp1
-rw-r--r--xbmc/music/MusicUtils.cpp1
-rw-r--r--xbmc/music/dialogs/GUIDialogMusicInfo.cpp1
-rw-r--r--xbmc/music/dialogs/GUIDialogSongInfo.h1
-rw-r--r--xbmc/music/infoscanner/MusicInfoScanner.cpp1
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp1
-rw-r--r--xbmc/music/windows/GUIWindowMusicNav.cpp1
-rw-r--r--xbmc/music/windows/GUIWindowMusicPlaylist.cpp1
-rw-r--r--xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp1
-rw-r--r--xbmc/music/windows/MusicFileItemListModifier.cpp1
-rw-r--r--xbmc/network/AirPlayServer.cpp1
-rw-r--r--xbmc/network/upnp/UPnPRenderer.cpp1
-rw-r--r--xbmc/network/upnp/UPnPServer.cpp1
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.cpp1
-rw-r--r--xbmc/peripherals/bus/PeripheralBus.cpp1
-rw-r--r--xbmc/peripherals/dialogs/GUIDialogPeripherals.h1
-rw-r--r--xbmc/pictures/GUIDialogPictureInfo.cpp1
-rw-r--r--xbmc/pictures/GUIViewStatePictures.cpp1
-rw-r--r--xbmc/pictures/GUIWindowPictures.cpp1
-rw-r--r--xbmc/pictures/GUIWindowSlideShow.cpp1
-rw-r--r--xbmc/pictures/PictureFolderImageFileLoader.cpp1
-rw-r--r--xbmc/pictures/PictureInfoLoader.cpp1
-rw-r--r--xbmc/pictures/PictureThumbLoader.cpp1
-rw-r--r--xbmc/platform/android/activity/CMakeLists.txt2
-rw-r--r--xbmc/platform/android/activity/JNIXBMCTextureCache.cpp42
-rw-r--r--xbmc/platform/android/activity/JNIXBMCTextureCache.h29
-rw-r--r--xbmc/platform/android/activity/android_main.cpp2
-rw-r--r--xbmc/platform/android/filesystem/APKDirectory.cpp1
-rw-r--r--xbmc/platform/android/filesystem/AndroidAppDirectory.cpp1
-rw-r--r--xbmc/platform/darwin/tvos/TVOSTopShelf.mm1
-rw-r--r--xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp1
-rw-r--r--xbmc/platform/posix/filesystem/PosixDirectory.cpp1
-rw-r--r--xbmc/platform/posix/filesystem/SMBDirectory.cpp1
-rw-r--r--xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp1
-rw-r--r--xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp1
-rw-r--r--xbmc/platform/win32/filesystem/Win32Directory.cpp1
-rw-r--r--xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp1
-rw-r--r--xbmc/playlists/PlayList.cpp1
-rw-r--r--xbmc/playlists/SmartPlaylistFileItemListModifier.cpp1
-rw-r--r--xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp1
-rw-r--r--xbmc/profiles/windows/GUIWindowSettingsProfile.cpp1
-rw-r--r--xbmc/programs/GUIViewStatePrograms.cpp1
-rw-r--r--xbmc/programs/GUIWindowPrograms.cpp1
-rw-r--r--xbmc/pvr/PVRChannelGroupImageFileLoader.cpp1
-rw-r--r--xbmc/pvr/PVRThumbLoader.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp1
-rw-r--r--xbmc/pvr/filesystem/PVRGUIDirectory.cpp1
-rw-r--r--xbmc/pvr/guilib/GUIEPGGridContainer.cpp1
-rw-r--r--xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsUtils.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp1
-rw-r--r--xbmc/pvr/windows/GUIViewStatePVR.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRBase.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRChannels.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRRecordings.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRSearch.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRTimers.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp1
-rw-r--r--xbmc/rendering/gles/GLESShader.cpp3
-rw-r--r--xbmc/rendering/gles/GLESShader.h6
-rw-r--r--xbmc/rendering/gles/RenderSystemGLES.cpp40
-rw-r--r--xbmc/rendering/gles/RenderSystemGLES.h5
-rw-r--r--xbmc/settings/windows/GUIControlSettings.cpp1
-rw-r--r--xbmc/test/TestBasicEnvironment.cpp1
-rw-r--r--xbmc/utils/FileOperationJob.h1
-rw-r--r--xbmc/utils/FontUtils.cpp1
-rw-r--r--xbmc/utils/GroupUtils.cpp1
-rw-r--r--xbmc/utils/RecentlyAddedJob.cpp1
-rw-r--r--xbmc/utils/SaveFileStateJob.cpp26
-rw-r--r--xbmc/utils/URIUtils.cpp10
-rw-r--r--xbmc/utils/test/TestVariant.cpp2
-rw-r--r--xbmc/video/ContextMenus.cpp6
-rw-r--r--xbmc/video/GUIViewStateVideo.cpp1
-rw-r--r--xbmc/video/VideoDatabase.cpp78
-rw-r--r--xbmc/video/VideoDatabase.h6
-rw-r--r--xbmc/video/VideoFileItemClassify.cpp16
-rw-r--r--xbmc/video/VideoFileItemClassify.h8
-rw-r--r--xbmc/video/VideoInfoScanner.cpp1
-rw-r--r--xbmc/video/VideoItemArtworkHandler.cpp1
-rw-r--r--xbmc/video/VideoThumbLoader.cpp3
-rw-r--r--xbmc/video/VideoUtils.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogCMSSettings.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogSubtitles.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoInfo.cpp18
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoManager.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp1
-rw-r--r--xbmc/video/guilib/VideoGUIUtils.cpp1
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.cpp1
-rw-r--r--xbmc/video/guilib/VideoVersionHelper.cpp15
-rw-r--r--xbmc/video/guilib/VideoVersionHelper.h7
-rw-r--r--xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp1
-rw-r--r--xbmc/video/jobs/VideoLibraryRefreshingJob.cpp1
-rw-r--r--xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp5
-rw-r--r--xbmc/video/tags/VideoTagLoaderNFO.cpp1
-rw-r--r--xbmc/video/tags/VideoTagLoaderPlugin.cpp1
-rw-r--r--xbmc/video/test/TestStacks.cpp1
-rw-r--r--xbmc/video/test/TestVideoFileItemClassify.cpp7
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp15
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.h2
-rw-r--r--xbmc/video/windows/GUIWindowVideoNav.cpp1
-rw-r--r--xbmc/video/windows/GUIWindowVideoPlaylist.cpp1
-rw-r--r--xbmc/video/windows/VideoFileItemListModifier.cpp1
-rw-r--r--xbmc/view/GUIViewControl.cpp1
-rw-r--r--xbmc/view/GUIViewState.cpp1
-rw-r--r--xbmc/windows/GUIMediaWindow.cpp60
-rw-r--r--xbmc/windows/GUIWindowLoginScreen.cpp1
286 files changed, 2330 insertions, 1623 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index cbf612389c..162bd67ca1 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -7289,7 +7289,9 @@ msgctxt "#13423"
msgid "Remember for this path"
msgstr ""
-#empty string with id 13424
+msgctxt "#13424"
+msgid "Choose playlist"
+msgstr ""
#: system/settings/settings.xml
msgctxt "#13425"
diff --git a/cmake/scripts/android/Install.cmake b/cmake/scripts/android/Install.cmake
index f88957cc9f..b912141007 100644
--- a/cmake/scripts/android/Install.cmake
+++ b/cmake/scripts/android/Install.cmake
@@ -48,6 +48,7 @@ set(package_files strings.xml
src/XBMCProperties.java
src/XBMCVideoView.java
src/XBMCFile.java
+ src/XBMCTextureCache.java
src/XBMCURIUtils.java
src/channels/SyncChannelJobService.java
src/channels/SyncProgramsJobService.java
diff --git a/system/shaders/GLES/2.0/gles_shader_clip.vert b/system/shaders/GLES/2.0/gles_shader_clip.vert
new file mode 100644
index 0000000000..513a24456c
--- /dev/null
+++ b/system/shaders/GLES/2.0/gles_shader_clip.vert
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 100
+
+attribute vec4 m_attrpos;
+attribute vec4 m_attrcol;
+attribute vec4 m_attrcord0;
+attribute vec4 m_attrcord1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying vec4 m_colour;
+uniform mat4 m_matrix;
+uniform vec4 m_shaderClip;
+uniform vec4 m_cordStep;
+
+// this shader can be used in cases where clipping via glScissor() is not
+// possible (e.g. when rotating). it can't discard triangles, but it may
+// degenerate them.
+
+void main()
+{
+ // limit the vertices to the clipping area
+ vec4 position = m_attrpos;
+ position.xy = clamp(position.xy, m_shaderClip.xy, m_shaderClip.zw);
+ gl_Position = m_matrix * position;
+
+ // correct texture coordinates for clipped vertices
+ vec2 clipDist = m_attrpos.xy - position.xy;
+ m_cord0.xy = m_attrcord0.xy - clipDist * m_cordStep.xy;
+ m_cord1.xy = m_attrcord1.xy - clipDist * m_cordStep.zw;
+
+ m_colour = m_attrcol;
+}
diff --git a/system/shaders/GLES/2.0/gles_shader_simple.vert b/system/shaders/GLES/2.0/gles_shader_simple.vert
new file mode 100644
index 0000000000..6d49788b65
--- /dev/null
+++ b/system/shaders/GLES/2.0/gles_shader_simple.vert
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 100
+
+attribute vec4 m_attrpos;
+attribute vec4 m_attrcol;
+attribute vec4 m_attrcord0;
+attribute vec4 m_attrcord1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying vec4 m_colour;
+uniform mat4 m_matrix;
+
+void main()
+{
+ gl_Position = m_matrix * m_attrpos;
+ m_colour = m_attrcol;
+ m_cord0 = m_attrcord0;
+ m_cord1 = m_attrcord1;
+}
diff --git a/tools/Linux/kodi.sh.in b/tools/Linux/kodi.sh.in
index 52d4646db5..3d86c86834 100644
--- a/tools/Linux/kodi.sh.in
+++ b/tools/Linux/kodi.sh.in
@@ -171,6 +171,7 @@ if command_exists gdb; then
fi
fi
+ENV_ARGS=
if [ -n "${KODI_AE_SINK}" ]; then
echo "KODI_AE_SINK env variable is deprecated and will be removed in the future."
@@ -197,11 +198,11 @@ if [ -n "${KODI_GL_INTERFACE}" ]; then
echo "Use the --gl-interface command line switch instead."
if [ "${KODI_GL_INTERFACE}" = "GLX" ]; then
- ENV_ARGS="--gl-interface=glx"
+ ENV_ARGS="${ENV_ARGS} --gl-interface=glx"
elif [ "${KODI_GL_INTERFACE}" = "EGL" ]; then
- ENV_ARGS="--gl-interface=egl"
+ ENV_ARGS="${ENV_ARGS} --gl-interface=egl"
elif [ "${KODI_GL_INTERFACE}" = "EGL_PB" ]; then
- ENV_ARGS="--gl-interface=egl-pb"
+ ENV_ARGS="${ENV_ARGS} --gl-interface=egl-pb"
fi
fi
diff --git a/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in b/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in
index 24d9239d89..9ec4a64641 100644
--- a/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in
+++ b/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in
@@ -24,15 +24,15 @@ import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;
+import @APP_PACKAGE@.content.XBMCFileContentProvider;
import @APP_PACKAGE@.model.Album;
+import @APP_PACKAGE@.model.File;
+import @APP_PACKAGE@.model.Media;
import @APP_PACKAGE@.model.Movie;
import @APP_PACKAGE@.model.MusicVideo;
import @APP_PACKAGE@.model.Song;
import @APP_PACKAGE@.model.TVEpisode;
import @APP_PACKAGE@.model.TVShow;
-import @APP_PACKAGE@.content.XBMCFileContentProvider;
-import @APP_PACKAGE@.model.File;
-import @APP_PACKAGE@.model.Media;
public class XBMCJsonRPC
{
@@ -63,6 +63,7 @@ public class XBMCJsonRPC
private String m_xbmc_web_url = "http://localhost:8080";
private HashSet<Integer> mRecomendationIds = new HashSet<Integer>();
+ private XBMCTextureCache mTextureCache = null;
private int MAX_RECOMMENDATIONS = 3;
@@ -126,6 +127,7 @@ public class XBMCJsonRPC
{
String jsonPort = XBMCProperties.getStringProperty("xbmc.jsonPort", "8080");
m_xbmc_web_url = "http://localhost:" + jsonPort;
+ mTextureCache = new XBMCTextureCache();
}
public String request_string(String jsonRequest)
@@ -864,7 +866,7 @@ public class XBMCJsonRPC
String poster = extractKeyFromArtMap(details, "poster");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("2:3");
}
// fallback to thumb
@@ -873,7 +875,7 @@ public class XBMCJsonRPC
poster = extractKeyFromArtMap(details, "thumb");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("16:9");
}
}
@@ -881,7 +883,7 @@ public class XBMCJsonRPC
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://movies/titles/" + details.get("movieid").getAsString() + "?showinfo=true");
@@ -935,7 +937,7 @@ public class XBMCJsonRPC
String poster = extractKeyFromArtMap(details, "poster");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("2:3");
}
// fallback to thumb
@@ -944,7 +946,7 @@ public class XBMCJsonRPC
poster = extractKeyFromArtMap(details, "thumb");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("16:9");
}
}
@@ -952,7 +954,7 @@ public class XBMCJsonRPC
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://tvshows/titles/" + details.get("tvshowid").getAsInt() + "/");
med.setCategory(Media.MEDIA_TYPE_TVSHOW);
@@ -982,14 +984,14 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("16:9");
}
// fanart
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://tvshows/titles/" + details.get("tvshowid").getAsInt() + "/" + details.get("episodeid").getAsInt() + "?showinfo=true");
@@ -1029,14 +1031,14 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
// fanart
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("musicdb://albums/" + details.get("albumid").getAsString() + "/");
@@ -1064,7 +1066,7 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "album.thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
// fallback to albumartist.thumb
@@ -1073,7 +1075,7 @@ public class XBMCJsonRPC
thumb = extractKeyFromArtMap(details, "albumartist.thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
else
@@ -1082,7 +1084,7 @@ public class XBMCJsonRPC
thumb = extractKeyFromArtMap(details, "artist.thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
}
@@ -1091,14 +1093,14 @@ public class XBMCJsonRPC
String fanart = extractKeyFromArtMap(details, "albumartist.fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
else
{
fanart = extractKeyFromArtMap(details, "artist.fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
}
@@ -1145,21 +1147,21 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
// fanart
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://musicvideos/titles/" + details.get("musicvideoid").getAsInt());
String url = getDownloadUrl(details.get("file").getAsString());
if (url != null && !url.isEmpty())
- med.setVideoUrl(XBMCFileContentProvider.buildUri(url).toString());
+ med.setVideoUrl(getImageUrl(url));
med.setCategory(Media.MEDIA_TYPE_MUSICVIDEO);
}
@@ -1438,4 +1440,23 @@ public class XBMCJsonRPC
return String.valueOf(rating / 2.0);
}
+ private String getImageUrl(String sUrl)
+ {
+ Log.d(TAG, "getImageUrl: sUrl = " + sUrl);
+ if (sUrl.startsWith("image://video@") || sUrl.startsWith("image://music@"))
+ {
+ Log.d(TAG, "getImageUrl: " + sUrl + " is not unwrapped");
+ return XBMCFileContentProvider.buildUri(sUrl).toString();
+ }
+
+ String sUnwrapImageUrl = this.mTextureCache.unwrapImageURL(sUrl);
+ Log.d(TAG, "getImageUrl: sUnwrapImageUrl = " + sUnwrapImageUrl);
+ if (!sUnwrapImageUrl.startsWith("http"))
+ {
+ return XBMCFileContentProvider.buildUri(sUrl).toString();
+ }
+
+ return sUnwrapImageUrl;
+ }
+
}
diff --git a/tools/android/packaging/xbmc/src/XBMCTextureCache.java.in b/tools/android/packaging/xbmc/src/XBMCTextureCache.java.in
new file mode 100644
index 0000000000..09dd7265f5
--- /dev/null
+++ b/tools/android/packaging/xbmc/src/XBMCTextureCache.java.in
@@ -0,0 +1,32 @@
+package @APP_PACKAGE@;
+
+import android.util.Log;
+
+/**
+ * Created by Maven85 on 16/03/2020.
+ */
+
+public class XBMCTextureCache
+{
+ native String _unwrapImageURL(String image);
+
+ private static final String TAG = "@APP_NAME@";
+
+ public XBMCTextureCache()
+ {
+ }
+
+ public String unwrapImageURL(String image)
+ {
+ try
+ {
+ return _unwrapImageURL(image);
+ }
+ catch (Exception e)
+ {
+ Log.e(TAG, "unwrapImageURL: Exception: " + e.getMessage());
+ return null;
+ }
+ }
+
+}
diff --git a/xbmc/AutoSwitch.cpp b/xbmc/AutoSwitch.cpp
index 14adb8e2bc..0dd710f757 100644
--- a/xbmc/AutoSwitch.cpp
+++ b/xbmc/AutoSwitch.cpp
@@ -9,6 +9,7 @@
#include "AutoSwitch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
diff --git a/xbmc/Autorun.cpp b/xbmc/Autorun.cpp
index 5d4145ac1b..aad71cf3c8 100644
--- a/xbmc/Autorun.cpp
+++ b/xbmc/Autorun.cpp
@@ -9,6 +9,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "PlayListPlayer.h"
diff --git a/xbmc/BackgroundInfoLoader.cpp b/xbmc/BackgroundInfoLoader.cpp
index 55d221ab04..de3d5a3a9e 100644
--- a/xbmc/BackgroundInfoLoader.cpp
+++ b/xbmc/BackgroundInfoLoader.cpp
@@ -9,6 +9,7 @@
#include "BackgroundInfoLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "threads/Thread.h"
#include "utils/log.h"
diff --git a/xbmc/CMakeLists.txt b/xbmc/CMakeLists.txt
index b7c838b3da..689f4af296 100644
--- a/xbmc/CMakeLists.txt
+++ b/xbmc/CMakeLists.txt
@@ -8,6 +8,7 @@ set(SOURCES AutoSwitch.cpp
DbUrl.cpp
DynamicDll.cpp
FileItem.cpp
+ FileItemList.cpp
FileItemListModification.cpp
GUIInfoManager.cpp
GUILargeTextureManager.cpp
@@ -45,6 +46,7 @@ set(HEADERS AutoSwitch.h
DllPaths_win32.h
DynamicDll.h
FileItem.h
+ FileItemList.h
FileItemListModification.h
GUIInfoManager.h
GUILargeTextureManager.h
diff --git a/xbmc/CueDocument.cpp b/xbmc/CueDocument.cpp
index 674a94aa51..abc5185e63 100644
--- a/xbmc/CueDocument.cpp
+++ b/xbmc/CueDocument.cpp
@@ -43,6 +43,7 @@
#include "CueDocument.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp
index 736bbbfe17..1029e0da61 100644
--- a/xbmc/FileItem.cpp
+++ b/xbmc/FileItem.cpp
@@ -9,6 +9,7 @@
#include "FileItem.h"
#include "CueDocument.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
@@ -17,7 +18,7 @@
#include "filesystem/Directory.h"
#include "filesystem/File.h"
#include "filesystem/MultiPathDirectory.h"
-#include "filesystem/MusicDatabaseDirectory.h"
+#include "filesystem/MusicDatabaseDirectory/QueryParams.h"
#include "filesystem/StackDirectory.h"
#include "filesystem/VideoDatabaseDirectory.h"
#include "filesystem/VideoDatabaseDirectory/QueryParams.h"
@@ -48,10 +49,8 @@
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
#include "utils/Archive.h"
-#include "utils/Crc32.h"
#include "utils/FileExtensionProvider.h"
#include "utils/Mime.h"
-#include "utils/Random.h"
#include "utils/RegExp.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
@@ -63,10 +62,8 @@
#include "video/VideoInfoTag.h"
#include "video/VideoUtils.h"
-#include <algorithm>
#include <cstdlib>
#include <memory>
-#include <mutex>
using namespace KODI;
using namespace KODI::VIDEO;
@@ -1562,6 +1559,9 @@ bool CFileItem::IsSamePath(const CFileItem *item) const
{
if (item->HasProperty("item_start") || HasProperty("item_start"))
return (item->GetProperty("item_start") == GetProperty("item_start"));
+ // See if we have associated a bluray playlist
+ if (IsBlurayPlaylist(*this) || IsBlurayPlaylist(*item))
+ return (GetDynPath() == item->GetDynPath());
return true;
}
if (HasMusicInfoTag() && item->HasMusicInfoTag())
@@ -1961,6 +1961,22 @@ void CFileItem::SetDynPath(const std::string &path)
m_strDynPath = path;
}
+std::string CFileItem::GetBlurayPath() const
+{
+ if (IsBlurayPlaylist(*this))
+ {
+ CURL url(GetDynPath());
+ CURL url2(url.GetHostName()); // strip bluray://
+ if (url2.IsProtocol("udf"))
+ // ISO
+ return url2.GetHostName(); // strip udf://
+ else if (url.IsProtocol("bluray"))
+ // BDMV
+ return url2.Get() + "BDMV/index.bdmv";
+ }
+ return GetDynPath();
+}
+
void CFileItem::SetCueDocument(const CCueDocumentPtr& cuePtr)
{
m_cueDocument = cuePtr;
@@ -2057,1083 +2073,6 @@ bool CFileItem::LoadTracksFromCueDocument(CFileItemList& scannedItems)
return tracksFound != 0;
}
-/////////////////////////////////////////////////////////////////////////////////
-/////
-///// CFileItemList
-/////
-//////////////////////////////////////////////////////////////////////////////////
-
-CFileItemList::CFileItemList()
-: CFileItem("", true)
-{
-}
-
-CFileItemList::CFileItemList(const std::string& strPath)
-: CFileItem(strPath, true)
-{
-}
-
-CFileItemList::~CFileItemList()
-{
- Clear();
-}
-
-CFileItemPtr CFileItemList::operator[] (int iItem)
-{
- return Get(iItem);
-}
-
-const CFileItemPtr CFileItemList::operator[] (int iItem) const
-{
- return Get(iItem);
-}
-
-CFileItemPtr CFileItemList::operator[] (const std::string& strPath)
-{
- return Get(strPath);
-}
-
-const CFileItemPtr CFileItemList::operator[] (const std::string& strPath) const
-{
- return Get(strPath);
-}
-
-void CFileItemList::SetIgnoreURLOptions(bool ignoreURLOptions)
-{
- m_ignoreURLOptions = ignoreURLOptions;
-
- if (m_fastLookup)
- {
- m_fastLookup = false; // Force SetFastlookup to clear map
- SetFastLookup(true); // and regenerate map
- }
-}
-
-void CFileItemList::SetFastLookup(bool fastLookup)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (fastLookup && !m_fastLookup)
- { // generate the map
- m_map.clear();
- for (unsigned int i=0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
- }
- }
- if (!fastLookup && m_fastLookup)
- m_map.clear();
- m_fastLookup = fastLookup;
-}
-
-bool CFileItemList::Contains(const std::string& fileName) const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (m_fastLookup)
- return m_map.find(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName) != m_map.end();
-
- // slow method...
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- const CFileItemPtr pItem = m_items[i];
- if (pItem->IsPath(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName))
- return true;
- }
- return false;
-}
-
-void CFileItemList::Clear()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- ClearItems();
- m_sortDescription.sortBy = SortByNone;
- m_sortDescription.sortOrder = SortOrderNone;
- m_sortDescription.sortAttributes = SortAttributeNone;
- m_sortIgnoreFolders = false;
- m_cacheToDisc = CACHE_IF_SLOW;
- m_sortDetails.clear();
- m_replaceListing = false;
- m_content.clear();
-}
-
-void CFileItemList::ClearItems()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- // make sure we free the memory of the items (these are GUIControls which may have allocated resources)
- FreeMemory();
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr item = m_items[i];
- item->FreeMemory();
- }
- m_items.clear();
- m_map.clear();
-}
-
-void CFileItemList::Add(CFileItemPtr pItem)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- if (m_fastLookup)
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
- m_items.emplace_back(std::move(pItem));
-}
-
-void CFileItemList::Add(CFileItem&& item)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- auto ptr = std::make_shared<CFileItem>(std::move(item));
- if (m_fastLookup)
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(ptr->GetPath()).GetWithoutOptions() : ptr->GetPath(), ptr));
- m_items.emplace_back(std::move(ptr));
-}
-
-void CFileItemList::AddFront(const CFileItemPtr &pItem, int itemPosition)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (itemPosition >= 0)
- {
- m_items.insert(m_items.begin()+itemPosition, pItem);
- }
- else
- {
- m_items.insert(m_items.begin()+(m_items.size()+itemPosition), pItem);
- }
- if (m_fastLookup)
- {
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
- }
-}
-
-void CFileItemList::Remove(CFileItem* pItem)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- for (IVECFILEITEMS it = m_items.begin(); it != m_items.end(); ++it)
- {
- if (pItem == it->get())
- {
- m_items.erase(it);
- if (m_fastLookup)
- {
- m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath());
- }
- break;
- }
- }
-}
-
-VECFILEITEMS::iterator CFileItemList::erase(VECFILEITEMS::iterator first,
- VECFILEITEMS::iterator last)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- return m_items.erase(first, last);
-}
-
-void CFileItemList::Remove(int iItem)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (iItem >= 0 && iItem < Size())
- {
- CFileItemPtr pItem = *(m_items.begin() + iItem);
- if (m_fastLookup)
- {
- m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath());
- }
- m_items.erase(m_items.begin() + iItem);
- }
-}
-
-void CFileItemList::Append(const CFileItemList& itemlist)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- for (int i = 0; i < itemlist.Size(); ++i)
- Add(itemlist[i]);
-}
-
-void CFileItemList::Assign(const CFileItemList& itemlist, bool append)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- if (!append)
- Clear();
- Append(itemlist);
- SetPath(itemlist.GetPath());
- SetLabel(itemlist.GetLabel());
- m_sortDetails = itemlist.m_sortDetails;
- m_sortDescription = itemlist.m_sortDescription;
- m_replaceListing = itemlist.m_replaceListing;
- m_content = itemlist.m_content;
- m_mapProperties = itemlist.m_mapProperties;
- m_cacheToDisc = itemlist.m_cacheToDisc;
-}
-
-bool CFileItemList::Copy(const CFileItemList& items, bool copyItems /* = true */)
-{
- // assign all CFileItem parts
- *static_cast<CFileItem*>(this) = static_cast<const CFileItem&>(items);
-
- // assign the rest of the CFileItemList properties
- m_replaceListing = items.m_replaceListing;
- m_content = items.m_content;
- m_mapProperties = items.m_mapProperties;
- m_cacheToDisc = items.m_cacheToDisc;
- m_sortDetails = items.m_sortDetails;
- m_sortDescription = items.m_sortDescription;
- m_sortIgnoreFolders = items.m_sortIgnoreFolders;
-
- if (copyItems)
- {
- // make a copy of each item
- for (int i = 0; i < items.Size(); i++)
- {
- CFileItemPtr newItem(new CFileItem(*items[i]));
- Add(newItem);
- }
- }
-
- return true;
-}
-
-CFileItemPtr CFileItemList::Get(int iItem) const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (iItem > -1 && iItem < (int)m_items.size())
- return m_items[iItem];
-
- return CFileItemPtr();
-}
-
-CFileItemPtr CFileItemList::Get(const std::string& strPath) const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (m_fastLookup)
- {
- MAPFILEITEMS::const_iterator it =
- m_map.find(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath);
- if (it != m_map.end())
- return it->second;
-
- return CFileItemPtr();
- }
- // slow method...
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->IsPath(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath))
- return pItem;
- }
-
- return CFileItemPtr();
-}
-
-int CFileItemList::Size() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- return (int)m_items.size();
-}
-
-bool CFileItemList::IsEmpty() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- return m_items.empty();
-}
-
-void CFileItemList::Reserve(size_t iCount)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- m_items.reserve(iCount);
-}
-
-void CFileItemList::Sort(FILEITEMLISTCOMPARISONFUNC func)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- std::stable_sort(m_items.begin(), m_items.end(), func);
-}
-
-void CFileItemList::FillSortFields(FILEITEMFILLFUNC func)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- std::for_each(m_items.begin(), m_items.end(), func);
-}
-
-void CFileItemList::Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes /* = SortAttributeNone */)
-{
- if (sortBy == SortByNone ||
- (m_sortDescription.sortBy == sortBy && m_sortDescription.sortOrder == sortOrder &&
- m_sortDescription.sortAttributes == sortAttributes))
- return;
-
- SortDescription sorting;
- sorting.sortBy = sortBy;
- sorting.sortOrder = sortOrder;
- sorting.sortAttributes = sortAttributes;
-
- Sort(sorting);
- m_sortDescription = sorting;
-}
-
-void CFileItemList::Sort(SortDescription sortDescription)
-{
- if (sortDescription.sortBy == SortByFile || sortDescription.sortBy == SortBySortTitle ||
- sortDescription.sortBy == SortByOriginalTitle || sortDescription.sortBy == SortByDateAdded ||
- sortDescription.sortBy == SortByRating || sortDescription.sortBy == SortByYear ||
- sortDescription.sortBy == SortByPlaylistOrder || sortDescription.sortBy == SortByLastPlayed ||
- sortDescription.sortBy == SortByPlaycount)
- sortDescription.sortAttributes = (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
-
- if (sortDescription.sortBy == SortByNone ||
- (m_sortDescription.sortBy == sortDescription.sortBy && m_sortDescription.sortOrder == sortDescription.sortOrder &&
- m_sortDescription.sortAttributes == sortDescription.sortAttributes))
- return;
-
- if (m_sortIgnoreFolders)
- sortDescription.sortAttributes = (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
-
- const Fields fields = SortUtils::GetFieldsForSorting(sortDescription.sortBy);
- SortItems sortItems((size_t)Size());
- for (int index = 0; index < Size(); index++)
- {
- sortItems[index] = std::make_shared<SortItem>();
- m_items[index]->ToSortable(*sortItems[index], fields);
- (*sortItems[index])[FieldId] = index;
- }
-
- // do the sorting
- SortUtils::Sort(sortDescription, sortItems);
-
- // apply the new order to the existing CFileItems
- VECFILEITEMS sortedFileItems;
- sortedFileItems.reserve(Size());
- for (SortItems::const_iterator it = sortItems.begin(); it != sortItems.end(); ++it)
- {
- CFileItemPtr item = m_items[(int)(*it)->at(FieldId).asInteger()];
- // Set the sort label in the CFileItem
- item->SetSortLabel((*it)->at(FieldSort).asWideString());
-
- sortedFileItems.push_back(item);
- }
-
- // replace the current list with the re-ordered one
- m_items = std::move(sortedFileItems);
-}
-
-void CFileItemList::Randomize()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- KODI::UTILS::RandomShuffle(m_items.begin(), m_items.end());
-}
-
-void CFileItemList::Archive(CArchive& ar)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- if (ar.IsStoring())
- {
- CFileItem::Archive(ar);
-
- int i = 0;
- if (!m_items.empty() && m_items[0]->IsParentFolder())
- i = 1;
-
- ar << (int)(m_items.size() - i);
-
- ar << m_ignoreURLOptions;
-
- ar << m_fastLookup;
-
- ar << (int)m_sortDescription.sortBy;
- ar << (int)m_sortDescription.sortOrder;
- ar << (int)m_sortDescription.sortAttributes;
- ar << m_sortIgnoreFolders;
- ar << (int)m_cacheToDisc;
-
- ar << (int)m_sortDetails.size();
- for (unsigned int j = 0; j < m_sortDetails.size(); ++j)
- {
- const GUIViewSortDetails &details = m_sortDetails[j];
- ar << (int)details.m_sortDescription.sortBy;
- ar << (int)details.m_sortDescription.sortOrder;
- ar << (int)details.m_sortDescription.sortAttributes;
- ar << details.m_buttonLabel;
- ar << details.m_labelMasks.m_strLabelFile;
- ar << details.m_labelMasks.m_strLabelFolder;
- ar << details.m_labelMasks.m_strLabel2File;
- ar << details.m_labelMasks.m_strLabel2Folder;
- }
-
- ar << m_content;
-
- for (; i < (int)m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- ar << *pItem;
- }
- }
- else
- {
- CFileItemPtr pParent;
- if (!IsEmpty())
- {
- CFileItemPtr pItem=m_items[0];
- if (pItem->IsParentFolder())
- pParent = std::make_shared<CFileItem>(*pItem);
- }
-
- SetIgnoreURLOptions(false);
- SetFastLookup(false);
- Clear();
-
- CFileItem::Archive(ar);
-
- int iSize = 0;
- ar >> iSize;
- if (iSize <= 0)
- return ;
-
- if (pParent)
- {
- m_items.reserve(iSize + 1);
- m_items.push_back(pParent);
- }
- else
- m_items.reserve(iSize);
-
- bool ignoreURLOptions = false;
- ar >> ignoreURLOptions;
-
- bool fastLookup = false;
- ar >> fastLookup;
-
- int tempint;
- ar >> tempint;
- m_sortDescription.sortBy = (SortBy)tempint;
- ar >> tempint;
- m_sortDescription.sortOrder = (SortOrder)tempint;
- ar >> tempint;
- m_sortDescription.sortAttributes = (SortAttribute)tempint;
- ar >> m_sortIgnoreFolders;
- ar >> tempint;
- m_cacheToDisc = CACHE_TYPE(tempint);
-
- unsigned int detailSize = 0;
- ar >> detailSize;
- for (unsigned int j = 0; j < detailSize; ++j)
- {
- GUIViewSortDetails details;
- ar >> tempint;
- details.m_sortDescription.sortBy = (SortBy)tempint;
- ar >> tempint;
- details.m_sortDescription.sortOrder = (SortOrder)tempint;
- ar >> tempint;
- details.m_sortDescription.sortAttributes = (SortAttribute)tempint;
- ar >> details.m_buttonLabel;
- ar >> details.m_labelMasks.m_strLabelFile;
- ar >> details.m_labelMasks.m_strLabelFolder;
- ar >> details.m_labelMasks.m_strLabel2File;
- ar >> details.m_labelMasks.m_strLabel2Folder;
- m_sortDetails.push_back(details);
- }
-
- ar >> m_content;
-
- for (int i = 0; i < iSize; ++i)
- {
- CFileItemPtr pItem(new CFileItem);
- ar >> *pItem;
- Add(pItem);
- }
-
- SetIgnoreURLOptions(ignoreURLOptions);
- SetFastLookup(fastLookup);
- }
-}
-
-void CFileItemList::FillInDefaultIcons()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- for (int i = 0; i < (int)m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- pItem->FillInDefaultIcon();
- }
-}
-
-int CFileItemList::GetFolderCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- int nFolderCount = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->m_bIsFolder)
- nFolderCount++;
- }
-
- return nFolderCount;
-}
-
-int CFileItemList::GetObjectCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- int numObjects = (int)m_items.size();
- if (numObjects && m_items[0]->IsParentFolder())
- numObjects--;
-
- return numObjects;
-}
-
-int CFileItemList::GetFileCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- int nFileCount = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (!pItem->m_bIsFolder)
- nFileCount++;
- }
-
- return nFileCount;
-}
-
-int CFileItemList::GetSelectedCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- int count = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->IsSelected())
- count++;
- }
-
- return count;
-}
-
-void CFileItemList::FilterCueItems()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- // Handle .CUE sheet files...
- std::vector<std::string> itemstodelete;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (!pItem->m_bIsFolder)
- { // see if it's a .CUE sheet
- if (pItem->IsCUESheet())
- {
- CCueDocumentPtr cuesheet(new CCueDocument);
- if (cuesheet->ParseFile(pItem->GetPath()))
- {
- std::vector<std::string> MediaFileVec;
- cuesheet->GetMediaFiles(MediaFileVec);
-
- // queue the cue sheet and the underlying media file for deletion
- for (std::vector<std::string>::iterator itMedia = MediaFileVec.begin();
- itMedia != MediaFileVec.end(); ++itMedia)
- {
- std::string strMediaFile = *itMedia;
- std::string fileFromCue = strMediaFile; // save the file from the cue we're matching against,
- // as we're going to search for others here...
- bool bFoundMediaFile = CFile::Exists(strMediaFile);
- if (!bFoundMediaFile)
- {
- // try file in same dir, not matching case...
- if (Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- }
- else
- {
- // try removing the .cue extension...
- strMediaFile = pItem->GetPath();
- URIUtils::RemoveExtension(strMediaFile);
- CFileItem item(strMediaFile, false);
- if (item.IsAudio() && Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- }
- else
- { // try replacing the extension with one of our allowed ones.
- std::vector<std::string> extensions = StringUtils::Split(CServiceBroker::GetFileExtensionProvider().GetMusicExtensions(), "|");
- for (std::vector<std::string>::const_iterator i = extensions.begin(); i != extensions.end(); ++i)
- {
- strMediaFile = URIUtils::ReplaceExtension(pItem->GetPath(), *i);
- CFileItem item(strMediaFile, false);
- if (!item.IsCUESheet() && !item.IsPlayList() && Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- break;
- }
- }
- }
- }
- }
- if (bFoundMediaFile)
- {
- cuesheet->UpdateMediaFile(fileFromCue, strMediaFile);
- // apply CUE for later processing
- for (int j = 0; j < (int)m_items.size(); j++)
- {
- CFileItemPtr pItem = m_items[j];
- if (StringUtils::CompareNoCase(pItem->GetPath(), strMediaFile) == 0)
- pItem->SetCueDocument(cuesheet);
- }
- }
- }
- }
- itemstodelete.push_back(pItem->GetPath());
- }
- }
- }
- // now delete the .CUE files.
- for (int i = 0; i < (int)itemstodelete.size(); i++)
- {
- for (int j = 0; j < (int)m_items.size(); j++)
- {
- CFileItemPtr pItem = m_items[j];
- if (StringUtils::CompareNoCase(pItem->GetPath(), itemstodelete[i]) == 0)
- { // delete this item
- m_items.erase(m_items.begin() + j);
- break;
- }
- }
- }
-}
-
-// Remove the extensions from the filenames
-void CFileItemList::RemoveExtensions()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- for (int i = 0; i < Size(); ++i)
- m_items[i]->RemoveExtension();
-}
-
-void CFileItemList::Stack(bool stackFiles /* = true */)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- // not allowed here
- if (IsVirtualDirectoryRoot() ||
- IsLiveTV() ||
- IsSourcesPath() ||
- IsLibraryFolder())
- return;
-
- SetProperty("isstacked", true);
-
- // items needs to be sorted for stuff below to work properly
- Sort(SortByLabel, SortOrderAscending);
-
- StackFolders();
-
- if (stackFiles)
- StackFiles();
-}
-
-void CFileItemList::StackFolders()
-{
- // Precompile our REs
- VECCREGEXP folderRegExps;
- CRegExp folderRegExp(true, CRegExp::autoUtf8);
- const std::vector<std::string>& strFolderRegExps = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_folderStackRegExps;
-
- std::vector<std::string>::const_iterator strExpression = strFolderRegExps.begin();
- while (strExpression != strFolderRegExps.end())
- {
- if (!folderRegExp.RegComp(*strExpression))
- CLog::Log(LOGERROR, "{}: Invalid folder stack RegExp:'{}'", __FUNCTION__,
- strExpression->c_str());
- else
- folderRegExps.push_back(folderRegExp);
-
- ++strExpression;
- }
-
- if (!folderRegExp.IsCompiled())
- {
- CLog::Log(LOGDEBUG, "{}: No stack expressions available. Skipping folder stacking",
- __FUNCTION__);
- return;
- }
-
- // stack folders
- for (int i = 0; i < Size(); i++)
- {
- CFileItemPtr item = Get(i);
- // combined the folder checks
- if (item->m_bIsFolder)
- {
- // only check known fast sources?
- // NOTES:
- // 1. rars and zips may be on slow sources? is this supposed to be allowed?
- if( !item->IsRemote()
- || item->IsSmb()
- || item->IsNfs()
- || URIUtils::IsInRAR(item->GetPath())
- || URIUtils::IsInZIP(item->GetPath())
- || URIUtils::IsOnLAN(item->GetPath())
- )
- {
- // stack cd# folders if contains only a single video file
-
- bool bMatch(false);
-
- VECCREGEXP::iterator expr = folderRegExps.begin();
- while (!bMatch && expr != folderRegExps.end())
- {
- //CLog::Log(LOGDEBUG,"{}: Running expression {} on {}", __FUNCTION__, expr->GetPattern(), item->GetLabel());
- bMatch = (expr->RegFind(item->GetLabel().c_str()) != -1);
- if (bMatch)
- {
- CFileItemList items;
- CDirectory::GetDirectory(item->GetPath(), items,
- CServiceBroker::GetFileExtensionProvider().GetVideoExtensions(),
- DIR_FLAG_DEFAULTS);
- // optimized to only traverse listing once by checking for filecount
- // and recording last file item for later use
- int nFiles = 0;
- int index = -1;
- for (int j = 0; j < items.Size(); j++)
- {
- if (!items[j]->m_bIsFolder)
- {
- nFiles++;
- index = j;
- }
-
- if (nFiles > 1)
- break;
- }
-
- if (nFiles == 1)
- *item = *items[index];
- }
- ++expr;
- }
-
- // check for dvd folders
- if (!bMatch)
- {
- std::string dvdPath = VIDEO_UTILS::GetOpticalMediaPath(*item);
-
- if (!dvdPath.empty())
- {
- // NOTE: should this be done for the CD# folders too?
- item->m_bIsFolder = false;
- item->SetPath(dvdPath);
- item->SetLabel2("");
- item->SetLabelPreformatted(true);
- m_sortDescription.sortBy = SortByNone; /* sorting is now broken */
- }
- }
- }
- }
- }
-}
-
-void CFileItemList::StackFiles()
-{
- // Precompile our REs
- VECCREGEXP stackRegExps;
- CRegExp tmpRegExp(true, CRegExp::autoUtf8);
- const std::vector<std::string>& strStackRegExps = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoStackRegExps;
- std::vector<std::string>::const_iterator strRegExp = strStackRegExps.begin();
- while (strRegExp != strStackRegExps.end())
- {
- if (tmpRegExp.RegComp(*strRegExp))
- {
- if (tmpRegExp.GetCaptureTotal() == 4)
- stackRegExps.push_back(tmpRegExp);
- else
- CLog::Log(LOGERROR, "Invalid video stack RE ({}). Must have 4 captures.", *strRegExp);
- }
- ++strRegExp;
- }
-
- // now stack the files, some of which may be from the previous stack iteration
- int i = 0;
- while (i < Size())
- {
- CFileItemPtr item1 = Get(i);
-
- // skip folders, nfo files, playlists
- if (item1->m_bIsFolder
- || item1->IsParentFolder()
- || item1->IsNFO()
- || item1->IsPlayList()
- )
- {
- // increment index
- i++;
- continue;
- }
-
- int64_t size = 0;
- size_t offset = 0;
- std::string stackName;
- std::string file1;
- std::string filePath;
- std::vector<int> stack;
- VECCREGEXP::iterator expr = stackRegExps.begin();
-
- URIUtils::Split(item1->GetPath(), filePath, file1);
- if (URIUtils::HasEncodedFilename(CURL(filePath)))
- file1 = CURL::Decode(file1);
-
- int j;
- while (expr != stackRegExps.end())
- {
- if (expr->RegFind(file1, offset) != -1)
- {
- std::string Title1 = expr->GetMatch(1),
- Volume1 = expr->GetMatch(2),
- Ignore1 = expr->GetMatch(3),
- Extension1 = expr->GetMatch(4);
- if (offset)
- Title1 = file1.substr(0, expr->GetSubStart(2));
- j = i + 1;
- while (j < Size())
- {
- CFileItemPtr item2 = Get(j);
-
- // skip folders, nfo files, playlists
- if (item2->m_bIsFolder
- || item2->IsParentFolder()
- || item2->IsNFO()
- || item2->IsPlayList()
- )
- {
- // increment index
- j++;
- continue;
- }
-
- std::string file2, filePath2;
- URIUtils::Split(item2->GetPath(), filePath2, file2);
- if (URIUtils::HasEncodedFilename(CURL(filePath2)) )
- file2 = CURL::Decode(file2);
-
- if (expr->RegFind(file2, offset) != -1)
- {
- std::string Title2 = expr->GetMatch(1),
- Volume2 = expr->GetMatch(2),
- Ignore2 = expr->GetMatch(3),
- Extension2 = expr->GetMatch(4);
- if (offset)
- Title2 = file2.substr(0, expr->GetSubStart(2));
- if (StringUtils::EqualsNoCase(Title1, Title2))
- {
- if (!StringUtils::EqualsNoCase(Volume1, Volume2))
- {
- if (StringUtils::EqualsNoCase(Ignore1, Ignore2) &&
- StringUtils::EqualsNoCase(Extension1, Extension2))
- {
- if (stack.empty())
- {
- stackName = Title1 + Ignore1 + Extension1;
- stack.push_back(i);
- size += item1->m_dwSize;
- }
- stack.push_back(j);
- size += item2->m_dwSize;
- }
- else // Sequel
- {
- offset = 0;
- ++expr;
- break;
- }
- }
- else if (!StringUtils::EqualsNoCase(Ignore1, Ignore2)) // False positive, try again with offset
- {
- offset = expr->GetSubStart(3);
- break;
- }
- else // Extension mismatch
- {
- offset = 0;
- ++expr;
- break;
- }
- }
- else // Title mismatch
- {
- offset = 0;
- ++expr;
- break;
- }
- }
- else // No match 2, next expression
- {
- offset = 0;
- ++expr;
- break;
- }
- j++;
- }
- if (j == Size())
- expr = stackRegExps.end();
- }
- else // No match 1
- {
- offset = 0;
- ++expr;
- }
- if (stack.size() > 1)
- {
- // have a stack, remove the items and add the stacked item
- // dont actually stack a multipart rar set, just remove all items but the first
- std::string stackPath;
- if (Get(stack[0])->IsRAR())
- stackPath = Get(stack[0])->GetPath();
- else
- {
- CStackDirectory dir;
- stackPath = dir.ConstructStackPath(*this, stack);
- }
- item1->SetPath(stackPath);
- // clean up list
- for (unsigned k = 1; k < stack.size(); k++)
- Remove(i+1);
- // item->m_bIsFolder = true; // don't treat stacked files as folders
- // the label may be in a different char set from the filename (eg over smb
- // the label is converted from utf8, but the filename is not)
- if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWEXTENSIONS))
- URIUtils::RemoveExtension(stackName);
-
- item1->SetLabel(stackName);
- item1->m_dwSize = size;
- break;
- }
- }
- i++;
- }
-}
-
-bool CFileItemList::Load(int windowID)
-{
- CFile file;
- auto path = GetDiscFileCache(windowID);
- try
- {
- if (file.Open(path))
- {
- CArchive ar(&file, CArchive::load);
- ar >> *this;
- CLog::Log(LOGDEBUG, "Loading items: {}, directory: {} sort method: {}, ascending: {}", Size(),
- CURL::GetRedacted(GetPath()), m_sortDescription.sortBy,
- m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
- ar.Close();
- file.Close();
- return true;
- }
- }
- catch(const std::out_of_range&)
- {
- CLog::Log(LOGERROR, "Corrupt archive: {}", CURL::GetRedacted(path));
- }
-
- return false;
-}
-
-bool CFileItemList::Save(int windowID)
-{
- int iSize = Size();
- if (iSize <= 0)
- return false;
-
- CLog::Log(LOGDEBUG, "Saving fileitems [{}]", CURL::GetRedacted(GetPath()));
-
- CFile file;
- std::string cachefile = GetDiscFileCache(windowID);
- if (file.OpenForWrite(cachefile, true)) // overwrite always
- {
- // Before caching save simplified cache file name in every item so the cache file can be
- // identifed and removed if the item is updated. List path and options (used for file
- // name when list cached) can not be accurately derived from item path.
- StringUtils::Replace(cachefile, "special://temp/archive_cache/", "");
- StringUtils::Replace(cachefile, ".fi", "");
- for (const auto& item : m_items)
- item->SetProperty("cachefilename", cachefile);
-
- CArchive ar(&file, CArchive::store);
- ar << *this;
- CLog::Log(LOGDEBUG, " -- items: {}, sort method: {}, ascending: {}", iSize,
- m_sortDescription.sortBy,
- m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
- ar.Close();
- file.Close();
- return true;
- }
-
- return false;
-}
-
-void CFileItemList::RemoveDiscCache(int windowID) const
-{
- RemoveDiscCache(GetDiscFileCache(windowID));
-}
-
-void CFileItemList::RemoveDiscCache(const std::string& cacheFile) const
-{
- if (CFile::Exists(cacheFile))
- {
- CLog::Log(LOGDEBUG, "Clearing cached fileitems [{}]", CURL::GetRedacted(GetPath()));
- CFile::Delete(cacheFile);
- }
-}
-
-void CFileItemList::RemoveDiscCacheCRC(const std::string& crc) const
-{
- std::string cachefile = StringUtils::Format("special://temp/archive_cache/{}.fi", crc);
- RemoveDiscCache(cachefile);
-}
-
-std::string CFileItemList::GetDiscFileCache(int windowID) const
-{
- std::string strPath(GetPath());
- URIUtils::RemoveSlashAtEnd(strPath);
-
- uint32_t crc = Crc32::ComputeFromLowerCase(strPath);
-
- if (IsCDDA() || IsOnDVD())
- return StringUtils::Format("special://temp/archive_cache/r-{:08x}.fi", crc);
-
- if (IsMusicDb())
- return StringUtils::Format("special://temp/archive_cache/mdb-{:08x}.fi", crc);
-
- if (IsVideoDb(*this))
- return StringUtils::Format("special://temp/archive_cache/vdb-{:08x}.fi", crc);
-
- if (IsSmartPlayList())
- return StringUtils::Format("special://temp/archive_cache/sp-{:08x}.fi", crc);
-
- if (windowID)
- return StringUtils::Format("special://temp/archive_cache/{}-{:08x}.fi", windowID, crc);
-
- return StringUtils::Format("special://temp/archive_cache/{:08x}.fi", crc);
-}
-
-bool CFileItemList::AlwaysCache() const
-{
- // some database folders are always cached
- if (IsMusicDb())
- return CMusicDatabaseDirectory::CanCache(GetPath());
- if (IsVideoDb(*this))
- return CVideoDatabaseDirectory::CanCache(GetPath());
- if (IsEPG())
- return true; // always cache
- return false;
-}
-
std::string CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */, bool fallbackToFolder /* = false */) const
{
if (m_strPath.empty()
@@ -3552,7 +2491,11 @@ std::string CFileItem::GetLocalMetadataPath() const
if (m_bIsFolder && !IsFileFolder())
return m_strPath;
- std::string parent(URIUtils::GetParentPath(m_strPath));
+ std::string parent{};
+ if (IsBlurayPlaylist(*this))
+ parent = URIUtils::GetParentPath(GetBlurayPath());
+ else
+ parent = URIUtils::GetParentPath(m_strPath);
std::string parentFolder(parent);
URIUtils::RemoveSlashAtEnd(parentFolder);
parentFolder = URIUtils::GetFileName(parentFolder);
@@ -3821,66 +2764,6 @@ bool CFileItem::LoadDetails()
return false;
}
-void CFileItemList::Swap(unsigned int item1, unsigned int item2)
-{
- if (item1 != item2 && item1 < m_items.size() && item2 < m_items.size())
- std::swap(m_items[item1], m_items[item2]);
-}
-
-bool CFileItemList::UpdateItem(const CFileItem *item)
-{
- if (!item)
- return false;
-
- std::unique_lock<CCriticalSection> lock(m_lock);
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->IsSamePath(item))
- {
- pItem->UpdateInfo(*item);
- return true;
- }
- }
- return false;
-}
-
-void CFileItemList::AddSortMethod(SortBy sortBy, int buttonLabel, const LABEL_MASKS &labelMasks, SortAttribute sortAttributes /* = SortAttributeNone */)
-{
- AddSortMethod(sortBy, sortAttributes, buttonLabel, labelMasks);
-}
-
-void CFileItemList::AddSortMethod(SortBy sortBy, SortAttribute sortAttributes, int buttonLabel, const LABEL_MASKS &labelMasks)
-{
- SortDescription sorting;
- sorting.sortBy = sortBy;
- sorting.sortAttributes = sortAttributes;
-
- AddSortMethod(sorting, buttonLabel, labelMasks);
-}
-
-void CFileItemList::AddSortMethod(SortDescription sortDescription, int buttonLabel, const LABEL_MASKS &labelMasks)
-{
- GUIViewSortDetails sort;
- sort.m_sortDescription = sortDescription;
- sort.m_buttonLabel = buttonLabel;
- sort.m_labelMasks = labelMasks;
-
- m_sortDetails.push_back(sort);
-}
-
-void CFileItemList::SetReplaceListing(bool replace)
-{
- m_replaceListing = replace;
-}
-
-void CFileItemList::ClearSortState()
-{
- m_sortDescription.sortBy = SortByNone;
- m_sortDescription.sortOrder = SortOrderNone;
- m_sortDescription.sortAttributes = SortAttributeNone;
-}
-
bool CFileItem::HasVideoInfoTag() const
{
// Note: CPVRRecording is derived from CVideoInfoTag
diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h
index ad2dae41a2..db0e8ed4be 100644
--- a/xbmc/FileItem.h
+++ b/xbmc/FileItem.h
@@ -142,6 +142,8 @@ public:
const std::string &GetDynPath() const;
void SetDynPath(const std::string &path);
+ std::string GetBlurayPath() const;
+
/*! \brief reset class to it's default values as per construction.
Free's all allocated memory.
\sa Initialize
@@ -610,6 +612,7 @@ public:
void LoadEmbeddedCue();
bool HasCueDocument() const;
bool LoadTracksFromCueDocument(CFileItemList& scannedItems);
+
private:
/*! \brief initialize all members of this class (not CGUIListItem members) to default values.
Called from constructors, and from Reset()
@@ -693,181 +696,4 @@ typedef std::map<std::string, CFileItemPtr > MAPFILEITEMS;
typedef std::pair<std::string, CFileItemPtr > MAPFILEITEMSPAIR;
typedef bool (*FILEITEMLISTCOMPARISONFUNC) (const CFileItemPtr &pItem1, const CFileItemPtr &pItem2);
-typedef void (*FILEITEMFILLFUNC) (CFileItemPtr &item);
-
-/*!
- \brief Represents a list of files
- \sa CFileItemList, CFileItem
- */
-class CFileItemList : public CFileItem
-{
-public:
- enum CACHE_TYPE { CACHE_NEVER = 0, CACHE_IF_SLOW, CACHE_ALWAYS };
-
- CFileItemList();
- explicit CFileItemList(const std::string& strPath);
- ~CFileItemList() override;
- void Archive(CArchive& ar) override;
- CFileItemPtr operator[] (int iItem);
- const CFileItemPtr operator[] (int iItem) const;
- CFileItemPtr operator[] (const std::string& strPath);
- const CFileItemPtr operator[] (const std::string& strPath) const;
- void Clear();
- void ClearItems();
- void Add(CFileItemPtr item);
- void Add(CFileItem&& item);
- void AddFront(const CFileItemPtr &pItem, int itemPosition);
- void Remove(CFileItem* pItem);
- void Remove(int iItem);
- CFileItemPtr Get(int iItem) const;
- const VECFILEITEMS& GetList() const { return m_items; }
- CFileItemPtr Get(const std::string& strPath) const;
- int Size() const;
- bool IsEmpty() const;
- void Append(const CFileItemList& itemlist);
- void Assign(const CFileItemList& itemlist, bool append = false);
- bool Copy (const CFileItemList& item, bool copyItems = true);
- void Reserve(size_t iCount);
- void Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes = SortAttributeNone);
- /* \brief Sorts the items based on the given sorting options
-
- In contrast to Sort (see above) this does not change the internal
- state by storing the sorting method and order used and therefore
- will always execute the sorting even if the list of items has
- already been sorted with the same options before.
- */
- void Sort(SortDescription sortDescription);
- void Randomize();
- void FillInDefaultIcons();
- int GetFolderCount() const;
- int GetFileCount() const;
- int GetSelectedCount() const;
- int GetObjectCount() const;
- void FilterCueItems();
- void RemoveExtensions();
- void SetIgnoreURLOptions(bool ignoreURLOptions);
- void SetFastLookup(bool fastLookup);
- bool Contains(const std::string& fileName) const;
- bool GetFastLookup() const { return m_fastLookup; }
-
- /*! \brief stack a CFileItemList
- By default we stack all items (files and folders) in a CFileItemList
- \param stackFiles whether to stack all items or just collapse folders (defaults to true)
- \sa StackFiles,StackFolders
- */
- void Stack(bool stackFiles = true);
-
- SortOrder GetSortOrder() const { return m_sortDescription.sortOrder; }
- SortBy GetSortMethod() const { return m_sortDescription.sortBy; }
- void SetSortOrder(SortOrder sortOrder) { m_sortDescription.sortOrder = sortOrder; }
- void SetSortMethod(SortBy sortBy) { m_sortDescription.sortBy = sortBy; }
-
- /*! \brief load a CFileItemList out of the cache
-
- The file list may be cached based on which window we're viewing in, as different
- windows will be listing different portions of the same URL (eg viewing music files
- versus viewing video files)
-
- \param windowID id of the window that's loading this list (defaults to 0)
- \return true if we loaded from the cache, false otherwise.
- \sa Save,RemoveDiscCache
- */
- bool Load(int windowID = 0);
-
- /*! \brief save a CFileItemList to the cache
-
- The file list may be cached based on which window we're viewing in, as different
- windows will be listing different portions of the same URL (eg viewing music files
- versus viewing video files)
-
- \param windowID id of the window that's saving this list (defaults to 0)
- \return true if successful, false otherwise.
- \sa Load,RemoveDiscCache
- */
- bool Save(int windowID = 0);
- void SetCacheToDisc(CACHE_TYPE cacheToDisc) { m_cacheToDisc = cacheToDisc; }
- bool CacheToDiscAlways() const { return m_cacheToDisc == CACHE_ALWAYS; }
- bool CacheToDiscIfSlow() const { return m_cacheToDisc == CACHE_IF_SLOW; }
- /*! \brief remove a previously cached CFileItemList from the cache
-
- The file list may be cached based on which window we're viewing in, as different
- windows will be listing different portions of the same URL (eg viewing music files
- versus viewing video files)
-
- \param windowID id of the window whose cache we which to remove (defaults to 0)
- \sa Save,Load
- */
- void RemoveDiscCache(int windowID = 0) const;
- void RemoveDiscCache(const std::string& cachefile) const;
- void RemoveDiscCacheCRC(const std::string& crc) const;
- bool AlwaysCache() const;
-
- void Swap(unsigned int item1, unsigned int item2);
-
- /*! \brief Update an item in the item list
- \param item the new item, which we match based on path to an existing item in the list
- \return true if the item exists in the list (and was thus updated), false otherwise.
- */
- bool UpdateItem(const CFileItem *item);
-
- void AddSortMethod(SortBy sortBy, int buttonLabel, const LABEL_MASKS &labelMasks, SortAttribute sortAttributes = SortAttributeNone);
- void AddSortMethod(SortBy sortBy, SortAttribute sortAttributes, int buttonLabel, const LABEL_MASKS &labelMasks);
- void AddSortMethod(SortDescription sortDescription, int buttonLabel, const LABEL_MASKS &labelMasks);
- bool HasSortDetails() const { return m_sortDetails.size() != 0; }
- const std::vector<GUIViewSortDetails> &GetSortDetails() const { return m_sortDetails; }
-
- /*! \brief Specify whether this list should be sorted with folders separate from files
- By default we sort with folders listed (and sorted separately) except for those sort modes
- which should be explicitly sorted with folders interleaved with files (eg SORT_METHOD_FILES).
- With this set the folder state will be ignored, allowing folders and files to sort interleaved.
- \param sort whether to ignore the folder state.
- */
- void SetSortIgnoreFolders(bool sort) { m_sortIgnoreFolders = sort; }
- bool GetReplaceListing() const { return m_replaceListing; }
- void SetReplaceListing(bool replace);
- void SetContent(const std::string& content) { m_content = content; }
- const std::string& GetContent() const { return m_content; }
-
- void ClearSortState();
-
- VECFILEITEMS::iterator begin() { return m_items.begin(); }
- VECFILEITEMS::iterator end() { return m_items.end(); }
- VECFILEITEMS::iterator erase(VECFILEITEMS::iterator first, VECFILEITEMS::iterator last);
- VECFILEITEMS::const_iterator begin() const { return m_items.begin(); }
- VECFILEITEMS::const_iterator end() const { return m_items.end(); }
- VECFILEITEMS::const_iterator cbegin() const { return m_items.cbegin(); }
- VECFILEITEMS::const_iterator cend() const { return m_items.cend(); }
- std::reverse_iterator<VECFILEITEMS::const_iterator> rbegin() const { return m_items.rbegin(); }
- std::reverse_iterator<VECFILEITEMS::const_iterator> rend() const { return m_items.rend(); }
-
-private:
- void Sort(FILEITEMLISTCOMPARISONFUNC func);
- void FillSortFields(FILEITEMFILLFUNC func);
- std::string GetDiscFileCache(int windowID) const;
-
- /*!
- \brief stack files in a CFileItemList
- \sa Stack
- */
- void StackFiles();
-
- /*!
- \brief stack folders in a CFileItemList
- \sa Stack
- */
- void StackFolders();
-
- VECFILEITEMS m_items;
- MAPFILEITEMS m_map;
- bool m_ignoreURLOptions = false;
- bool m_fastLookup = false;
- SortDescription m_sortDescription;
- bool m_sortIgnoreFolders = false;
- CACHE_TYPE m_cacheToDisc = CACHE_IF_SLOW;
- bool m_replaceListing = false;
- std::string m_content;
-
- std::vector<GUIViewSortDetails> m_sortDetails;
-
- mutable CCriticalSection m_lock;
-};
+typedef void (*FILEITEMFILLFUNC)(CFileItemPtr& item);
diff --git a/xbmc/FileItemList.cpp b/xbmc/FileItemList.cpp
new file mode 100644
index 0000000000..0ba0abbc8c
--- /dev/null
+++ b/xbmc/FileItemList.cpp
@@ -0,0 +1,1174 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "FileItemList.h"
+
+#include "CueDocument.h"
+#include "ServiceBroker.h"
+#include "URL.h"
+#include "filesystem/Directory.h"
+#include "filesystem/File.h"
+#include "filesystem/MusicDatabaseDirectory.h"
+#include "filesystem/StackDirectory.h"
+#include "filesystem/VideoDatabaseDirectory.h"
+#include "settings/AdvancedSettings.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "utils/Archive.h"
+#include "utils/Crc32.h"
+#include "utils/FileExtensionProvider.h"
+#include "utils/Random.h"
+#include "utils/RegExp.h"
+#include "utils/URIUtils.h"
+#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
+#include "video/VideoUtils.h"
+
+#include <algorithm>
+
+using namespace KODI;
+using namespace XFILE;
+
+CFileItemList::CFileItemList() : CFileItem("", true)
+{
+}
+
+CFileItemList::CFileItemList(const std::string& strPath) : CFileItem(strPath, true)
+{
+}
+
+CFileItemList::~CFileItemList()
+{
+ Clear();
+}
+
+CFileItemPtr CFileItemList::operator[](int iItem)
+{
+ return Get(iItem);
+}
+
+const CFileItemPtr CFileItemList::operator[](int iItem) const
+{
+ return Get(iItem);
+}
+
+CFileItemPtr CFileItemList::operator[](const std::string& strPath)
+{
+ return Get(strPath);
+}
+
+const CFileItemPtr CFileItemList::operator[](const std::string& strPath) const
+{
+ return Get(strPath);
+}
+
+void CFileItemList::SetIgnoreURLOptions(bool ignoreURLOptions)
+{
+ m_ignoreURLOptions = ignoreURLOptions;
+
+ if (m_fastLookup)
+ {
+ m_fastLookup = false; // Force SetFastlookup to clear map
+ SetFastLookup(true); // and regenerate map
+ }
+}
+
+void CFileItemList::SetFastLookup(bool fastLookup)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (fastLookup && !m_fastLookup)
+ { // generate the map
+ m_map.clear();
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions()
+ : pItem->GetPath(),
+ pItem));
+ }
+ }
+ if (!fastLookup && m_fastLookup)
+ m_map.clear();
+ m_fastLookup = fastLookup;
+}
+
+bool CFileItemList::Contains(const std::string& fileName) const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (m_fastLookup)
+ return m_map.find(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName) !=
+ m_map.end();
+
+ // slow method...
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ const CFileItemPtr pItem = m_items[i];
+ if (pItem->IsPath(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName))
+ return true;
+ }
+ return false;
+}
+
+void CFileItemList::Clear()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ ClearItems();
+ m_sortDescription.sortBy = SortByNone;
+ m_sortDescription.sortOrder = SortOrderNone;
+ m_sortDescription.sortAttributes = SortAttributeNone;
+ m_sortIgnoreFolders = false;
+ m_cacheToDisc = CACHE_IF_SLOW;
+ m_sortDetails.clear();
+ m_replaceListing = false;
+ m_content.clear();
+}
+
+void CFileItemList::ClearItems()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ // make sure we free the memory of the items (these are GUIControls which may have allocated resources)
+ FreeMemory();
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr item = m_items[i];
+ item->FreeMemory();
+ }
+ m_items.clear();
+ m_map.clear();
+}
+
+void CFileItemList::Add(CFileItemPtr pItem)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ if (m_fastLookup)
+ m_map.insert(MAPFILEITEMSPAIR(
+ m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
+ m_items.emplace_back(std::move(pItem));
+}
+
+void CFileItemList::Add(CFileItem&& item)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ auto ptr = std::make_shared<CFileItem>(std::move(item));
+ if (m_fastLookup)
+ m_map.insert(MAPFILEITEMSPAIR(
+ m_ignoreURLOptions ? CURL(ptr->GetPath()).GetWithoutOptions() : ptr->GetPath(), ptr));
+ m_items.emplace_back(std::move(ptr));
+}
+
+void CFileItemList::AddFront(const CFileItemPtr& pItem, int itemPosition)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (itemPosition >= 0)
+ {
+ m_items.insert(m_items.begin() + itemPosition, pItem);
+ }
+ else
+ {
+ m_items.insert(m_items.begin() + (m_items.size() + itemPosition), pItem);
+ }
+ if (m_fastLookup)
+ {
+ m_map.insert(MAPFILEITEMSPAIR(
+ m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
+ }
+}
+
+void CFileItemList::Remove(CFileItem* pItem)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ for (IVECFILEITEMS it = m_items.begin(); it != m_items.end(); ++it)
+ {
+ if (pItem == it->get())
+ {
+ m_items.erase(it);
+ if (m_fastLookup)
+ {
+ m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions()
+ : pItem->GetPath());
+ }
+ break;
+ }
+ }
+}
+
+VECFILEITEMS::iterator CFileItemList::erase(VECFILEITEMS::iterator first,
+ VECFILEITEMS::iterator last)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ return m_items.erase(first, last);
+}
+
+void CFileItemList::Remove(int iItem)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (iItem >= 0 && iItem < Size())
+ {
+ CFileItemPtr pItem = *(m_items.begin() + iItem);
+ if (m_fastLookup)
+ {
+ m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions()
+ : pItem->GetPath());
+ }
+ m_items.erase(m_items.begin() + iItem);
+ }
+}
+
+void CFileItemList::Append(const CFileItemList& itemlist)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ for (int i = 0; i < itemlist.Size(); ++i)
+ Add(itemlist[i]);
+}
+
+void CFileItemList::Assign(const CFileItemList& itemlist, bool append)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ if (!append)
+ Clear();
+ Append(itemlist);
+ SetPath(itemlist.GetPath());
+ SetLabel(itemlist.GetLabel());
+ m_sortDetails = itemlist.m_sortDetails;
+ m_sortDescription = itemlist.m_sortDescription;
+ m_replaceListing = itemlist.m_replaceListing;
+ m_content = itemlist.m_content;
+ m_mapProperties = itemlist.m_mapProperties;
+ m_cacheToDisc = itemlist.m_cacheToDisc;
+}
+
+bool CFileItemList::Copy(const CFileItemList& items, bool copyItems /* = true */)
+{
+ // assign all CFileItem parts
+ *static_cast<CFileItem*>(this) = static_cast<const CFileItem&>(items);
+
+ // assign the rest of the CFileItemList properties
+ m_replaceListing = items.m_replaceListing;
+ m_content = items.m_content;
+ m_mapProperties = items.m_mapProperties;
+ m_cacheToDisc = items.m_cacheToDisc;
+ m_sortDetails = items.m_sortDetails;
+ m_sortDescription = items.m_sortDescription;
+ m_sortIgnoreFolders = items.m_sortIgnoreFolders;
+
+ if (copyItems)
+ {
+ // make a copy of each item
+ for (int i = 0; i < items.Size(); i++)
+ {
+ CFileItemPtr newItem(new CFileItem(*items[i]));
+ Add(newItem);
+ }
+ }
+
+ return true;
+}
+
+CFileItemPtr CFileItemList::Get(int iItem) const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (iItem > -1 && iItem < (int)m_items.size())
+ return m_items[iItem];
+
+ return CFileItemPtr();
+}
+
+CFileItemPtr CFileItemList::Get(const std::string& strPath) const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (m_fastLookup)
+ {
+ MAPFILEITEMS::const_iterator it =
+ m_map.find(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath);
+ if (it != m_map.end())
+ return it->second;
+
+ return CFileItemPtr();
+ }
+ // slow method...
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->IsPath(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath))
+ return pItem;
+ }
+
+ return CFileItemPtr();
+}
+
+int CFileItemList::Size() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ return (int)m_items.size();
+}
+
+bool CFileItemList::IsEmpty() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ return m_items.empty();
+}
+
+void CFileItemList::Reserve(size_t iCount)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ m_items.reserve(iCount);
+}
+
+void CFileItemList::Sort(FILEITEMLISTCOMPARISONFUNC func)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ std::stable_sort(m_items.begin(), m_items.end(), func);
+}
+
+void CFileItemList::FillSortFields(FILEITEMFILLFUNC func)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ std::for_each(m_items.begin(), m_items.end(), func);
+}
+
+void CFileItemList::Sort(SortBy sortBy,
+ SortOrder sortOrder,
+ SortAttribute sortAttributes /* = SortAttributeNone */)
+{
+ if (sortBy == SortByNone ||
+ (m_sortDescription.sortBy == sortBy && m_sortDescription.sortOrder == sortOrder &&
+ m_sortDescription.sortAttributes == sortAttributes))
+ return;
+
+ SortDescription sorting;
+ sorting.sortBy = sortBy;
+ sorting.sortOrder = sortOrder;
+ sorting.sortAttributes = sortAttributes;
+
+ Sort(sorting);
+ m_sortDescription = sorting;
+}
+
+void CFileItemList::Sort(SortDescription sortDescription)
+{
+ if (sortDescription.sortBy == SortByFile || sortDescription.sortBy == SortBySortTitle ||
+ sortDescription.sortBy == SortByOriginalTitle || sortDescription.sortBy == SortByDateAdded ||
+ sortDescription.sortBy == SortByRating || sortDescription.sortBy == SortByYear ||
+ sortDescription.sortBy == SortByPlaylistOrder || sortDescription.sortBy == SortByLastPlayed ||
+ sortDescription.sortBy == SortByPlaycount)
+ sortDescription.sortAttributes =
+ (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
+
+ if (sortDescription.sortBy == SortByNone ||
+ (m_sortDescription.sortBy == sortDescription.sortBy &&
+ m_sortDescription.sortOrder == sortDescription.sortOrder &&
+ m_sortDescription.sortAttributes == sortDescription.sortAttributes))
+ return;
+
+ if (m_sortIgnoreFolders)
+ sortDescription.sortAttributes =
+ (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
+
+ const Fields fields = SortUtils::GetFieldsForSorting(sortDescription.sortBy);
+ SortItems sortItems((size_t)Size());
+ for (int index = 0; index < Size(); index++)
+ {
+ sortItems[index] = std::make_shared<SortItem>();
+ m_items[index]->ToSortable(*sortItems[index], fields);
+ (*sortItems[index])[FieldId] = index;
+ }
+
+ // do the sorting
+ SortUtils::Sort(sortDescription, sortItems);
+
+ // apply the new order to the existing CFileItems
+ VECFILEITEMS sortedFileItems;
+ sortedFileItems.reserve(Size());
+ for (SortItems::const_iterator it = sortItems.begin(); it != sortItems.end(); ++it)
+ {
+ CFileItemPtr item = m_items[(int)(*it)->at(FieldId).asInteger()];
+ // Set the sort label in the CFileItem
+ item->SetSortLabel((*it)->at(FieldSort).asWideString());
+
+ sortedFileItems.push_back(item);
+ }
+
+ // replace the current list with the re-ordered one
+ m_items = std::move(sortedFileItems);
+}
+
+void CFileItemList::Randomize()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ KODI::UTILS::RandomShuffle(m_items.begin(), m_items.end());
+}
+
+void CFileItemList::Archive(CArchive& ar)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ if (ar.IsStoring())
+ {
+ CFileItem::Archive(ar);
+
+ int i = 0;
+ if (!m_items.empty() && m_items[0]->IsParentFolder())
+ i = 1;
+
+ ar << (int)(m_items.size() - i);
+
+ ar << m_ignoreURLOptions;
+
+ ar << m_fastLookup;
+
+ ar << (int)m_sortDescription.sortBy;
+ ar << (int)m_sortDescription.sortOrder;
+ ar << (int)m_sortDescription.sortAttributes;
+ ar << m_sortIgnoreFolders;
+ ar << (int)m_cacheToDisc;
+
+ ar << (int)m_sortDetails.size();
+ for (unsigned int j = 0; j < m_sortDetails.size(); ++j)
+ {
+ const GUIViewSortDetails& details = m_sortDetails[j];
+ ar << (int)details.m_sortDescription.sortBy;
+ ar << (int)details.m_sortDescription.sortOrder;
+ ar << (int)details.m_sortDescription.sortAttributes;
+ ar << details.m_buttonLabel;
+ ar << details.m_labelMasks.m_strLabelFile;
+ ar << details.m_labelMasks.m_strLabelFolder;
+ ar << details.m_labelMasks.m_strLabel2File;
+ ar << details.m_labelMasks.m_strLabel2Folder;
+ }
+
+ ar << m_content;
+
+ for (; i < (int)m_items.size(); ++i)
+ {
+ CFileItemPtr pItem = m_items[i];
+ ar << *pItem;
+ }
+ }
+ else
+ {
+ CFileItemPtr pParent;
+ if (!IsEmpty())
+ {
+ CFileItemPtr pItem = m_items[0];
+ if (pItem->IsParentFolder())
+ pParent = std::make_shared<CFileItem>(*pItem);
+ }
+
+ SetIgnoreURLOptions(false);
+ SetFastLookup(false);
+ Clear();
+
+ CFileItem::Archive(ar);
+
+ int iSize = 0;
+ ar >> iSize;
+ if (iSize <= 0)
+ return;
+
+ if (pParent)
+ {
+ m_items.reserve(iSize + 1);
+ m_items.push_back(pParent);
+ }
+ else
+ m_items.reserve(iSize);
+
+ bool ignoreURLOptions = false;
+ ar >> ignoreURLOptions;
+
+ bool fastLookup = false;
+ ar >> fastLookup;
+
+ int tempint;
+ ar >> tempint;
+ m_sortDescription.sortBy = (SortBy)tempint;
+ ar >> tempint;
+ m_sortDescription.sortOrder = (SortOrder)tempint;
+ ar >> tempint;
+ m_sortDescription.sortAttributes = (SortAttribute)tempint;
+ ar >> m_sortIgnoreFolders;
+ ar >> tempint;
+ m_cacheToDisc = CACHE_TYPE(tempint);
+
+ unsigned int detailSize = 0;
+ ar >> detailSize;
+ for (unsigned int j = 0; j < detailSize; ++j)
+ {
+ GUIViewSortDetails details;
+ ar >> tempint;
+ details.m_sortDescription.sortBy = (SortBy)tempint;
+ ar >> tempint;
+ details.m_sortDescription.sortOrder = (SortOrder)tempint;
+ ar >> tempint;
+ details.m_sortDescription.sortAttributes = (SortAttribute)tempint;
+ ar >> details.m_buttonLabel;
+ ar >> details.m_labelMasks.m_strLabelFile;
+ ar >> details.m_labelMasks.m_strLabelFolder;
+ ar >> details.m_labelMasks.m_strLabel2File;
+ ar >> details.m_labelMasks.m_strLabel2Folder;
+ m_sortDetails.push_back(details);
+ }
+
+ ar >> m_content;
+
+ for (int i = 0; i < iSize; ++i)
+ {
+ CFileItemPtr pItem(new CFileItem);
+ ar >> *pItem;
+ Add(pItem);
+ }
+
+ SetIgnoreURLOptions(ignoreURLOptions);
+ SetFastLookup(fastLookup);
+ }
+}
+
+void CFileItemList::FillInDefaultIcons()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ for (int i = 0; i < (int)m_items.size(); ++i)
+ {
+ CFileItemPtr pItem = m_items[i];
+ pItem->FillInDefaultIcon();
+ }
+}
+
+int CFileItemList::GetFolderCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ int nFolderCount = 0;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->m_bIsFolder)
+ nFolderCount++;
+ }
+
+ return nFolderCount;
+}
+
+int CFileItemList::GetObjectCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ int numObjects = (int)m_items.size();
+ if (numObjects && m_items[0]->IsParentFolder())
+ numObjects--;
+
+ return numObjects;
+}
+
+int CFileItemList::GetFileCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ int nFileCount = 0;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (!pItem->m_bIsFolder)
+ nFileCount++;
+ }
+
+ return nFileCount;
+}
+
+int CFileItemList::GetSelectedCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ int count = 0;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->IsSelected())
+ count++;
+ }
+
+ return count;
+}
+
+void CFileItemList::FilterCueItems()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ // Handle .CUE sheet files...
+ std::vector<std::string> itemstodelete;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (!pItem->m_bIsFolder)
+ { // see if it's a .CUE sheet
+ if (pItem->IsCUESheet())
+ {
+ CCueDocumentPtr cuesheet(new CCueDocument);
+ if (cuesheet->ParseFile(pItem->GetPath()))
+ {
+ std::vector<std::string> MediaFileVec;
+ cuesheet->GetMediaFiles(MediaFileVec);
+
+ // queue the cue sheet and the underlying media file for deletion
+ for (std::vector<std::string>::iterator itMedia = MediaFileVec.begin();
+ itMedia != MediaFileVec.end(); ++itMedia)
+ {
+ std::string strMediaFile = *itMedia;
+ std::string fileFromCue =
+ strMediaFile; // save the file from the cue we're matching against,
+ // as we're going to search for others here...
+ bool bFoundMediaFile = CFile::Exists(strMediaFile);
+ if (!bFoundMediaFile)
+ {
+ // try file in same dir, not matching case...
+ if (Contains(strMediaFile))
+ {
+ bFoundMediaFile = true;
+ }
+ else
+ {
+ // try removing the .cue extension...
+ strMediaFile = pItem->GetPath();
+ URIUtils::RemoveExtension(strMediaFile);
+ CFileItem item(strMediaFile, false);
+ if (item.IsAudio() && Contains(strMediaFile))
+ {
+ bFoundMediaFile = true;
+ }
+ else
+ { // try replacing the extension with one of our allowed ones.
+ std::vector<std::string> extensions = StringUtils::Split(
+ CServiceBroker::GetFileExtensionProvider().GetMusicExtensions(), "|");
+ for (std::vector<std::string>::const_iterator i = extensions.begin();
+ i != extensions.end(); ++i)
+ {
+ strMediaFile = URIUtils::ReplaceExtension(pItem->GetPath(), *i);
+ CFileItem item(strMediaFile, false);
+ if (!item.IsCUESheet() && !item.IsPlayList() && Contains(strMediaFile))
+ {
+ bFoundMediaFile = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (bFoundMediaFile)
+ {
+ cuesheet->UpdateMediaFile(fileFromCue, strMediaFile);
+ // apply CUE for later processing
+ for (int j = 0; j < (int)m_items.size(); j++)
+ {
+ CFileItemPtr pItem = m_items[j];
+ if (StringUtils::CompareNoCase(pItem->GetPath(), strMediaFile) == 0)
+ pItem->SetCueDocument(cuesheet);
+ }
+ }
+ }
+ }
+ itemstodelete.push_back(pItem->GetPath());
+ }
+ }
+ }
+ // now delete the .CUE files.
+ for (int i = 0; i < (int)itemstodelete.size(); i++)
+ {
+ for (int j = 0; j < (int)m_items.size(); j++)
+ {
+ CFileItemPtr pItem = m_items[j];
+ if (StringUtils::CompareNoCase(pItem->GetPath(), itemstodelete[i]) == 0)
+ { // delete this item
+ m_items.erase(m_items.begin() + j);
+ break;
+ }
+ }
+ }
+}
+
+// Remove the extensions from the filenames
+void CFileItemList::RemoveExtensions()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ for (int i = 0; i < Size(); ++i)
+ m_items[i]->RemoveExtension();
+}
+
+void CFileItemList::Stack(bool stackFiles /* = true */)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ // not allowed here
+ if (IsVirtualDirectoryRoot() || IsLiveTV() || IsSourcesPath() || IsLibraryFolder())
+ return;
+
+ SetProperty("isstacked", true);
+
+ // items needs to be sorted for stuff below to work properly
+ Sort(SortByLabel, SortOrderAscending);
+
+ StackFolders();
+
+ if (stackFiles)
+ StackFiles();
+}
+
+void CFileItemList::StackFolders()
+{
+ // Precompile our REs
+ VECCREGEXP folderRegExps;
+ CRegExp folderRegExp(true, CRegExp::autoUtf8);
+ const std::vector<std::string>& strFolderRegExps =
+ CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_folderStackRegExps;
+
+ std::vector<std::string>::const_iterator strExpression = strFolderRegExps.begin();
+ while (strExpression != strFolderRegExps.end())
+ {
+ if (!folderRegExp.RegComp(*strExpression))
+ CLog::Log(LOGERROR, "{}: Invalid folder stack RegExp:'{}'", __FUNCTION__,
+ strExpression->c_str());
+ else
+ folderRegExps.push_back(folderRegExp);
+
+ ++strExpression;
+ }
+
+ if (!folderRegExp.IsCompiled())
+ {
+ CLog::Log(LOGDEBUG, "{}: No stack expressions available. Skipping folder stacking",
+ __FUNCTION__);
+ return;
+ }
+
+ // stack folders
+ for (int i = 0; i < Size(); i++)
+ {
+ CFileItemPtr item = Get(i);
+ // combined the folder checks
+ if (item->m_bIsFolder)
+ {
+ // only check known fast sources?
+ // NOTES:
+ // 1. rars and zips may be on slow sources? is this supposed to be allowed?
+ if (!item->IsRemote() || item->IsSmb() || item->IsNfs() ||
+ URIUtils::IsInRAR(item->GetPath()) || URIUtils::IsInZIP(item->GetPath()) ||
+ URIUtils::IsOnLAN(item->GetPath()))
+ {
+ // stack cd# folders if contains only a single video file
+
+ bool bMatch(false);
+
+ VECCREGEXP::iterator expr = folderRegExps.begin();
+ while (!bMatch && expr != folderRegExps.end())
+ {
+ //CLog::Log(LOGDEBUG,"{}: Running expression {} on {}", __FUNCTION__, expr->GetPattern(), item->GetLabel());
+ bMatch = (expr->RegFind(item->GetLabel().c_str()) != -1);
+ if (bMatch)
+ {
+ CFileItemList items;
+ CDirectory::GetDirectory(
+ item->GetPath(), items,
+ CServiceBroker::GetFileExtensionProvider().GetVideoExtensions(), DIR_FLAG_DEFAULTS);
+ // optimized to only traverse listing once by checking for filecount
+ // and recording last file item for later use
+ int nFiles = 0;
+ int index = -1;
+ for (int j = 0; j < items.Size(); j++)
+ {
+ if (!items[j]->m_bIsFolder)
+ {
+ nFiles++;
+ index = j;
+ }
+
+ if (nFiles > 1)
+ break;
+ }
+
+ if (nFiles == 1)
+ *item = *items[index];
+ }
+ ++expr;
+ }
+
+ // check for dvd folders
+ if (!bMatch)
+ {
+ std::string dvdPath = VIDEO_UTILS::GetOpticalMediaPath(*item);
+
+ if (!dvdPath.empty())
+ {
+ // NOTE: should this be done for the CD# folders too?
+ item->m_bIsFolder = false;
+ item->SetPath(dvdPath);
+ item->SetLabel2("");
+ item->SetLabelPreformatted(true);
+ m_sortDescription.sortBy = SortByNone; /* sorting is now broken */
+ }
+ }
+ }
+ }
+ }
+}
+
+void CFileItemList::StackFiles()
+{
+ // Precompile our REs
+ VECCREGEXP stackRegExps;
+ CRegExp tmpRegExp(true, CRegExp::autoUtf8);
+ const std::vector<std::string>& strStackRegExps =
+ CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoStackRegExps;
+ std::vector<std::string>::const_iterator strRegExp = strStackRegExps.begin();
+ while (strRegExp != strStackRegExps.end())
+ {
+ if (tmpRegExp.RegComp(*strRegExp))
+ {
+ if (tmpRegExp.GetCaptureTotal() == 4)
+ stackRegExps.push_back(tmpRegExp);
+ else
+ CLog::Log(LOGERROR, "Invalid video stack RE ({}). Must have 4 captures.", *strRegExp);
+ }
+ ++strRegExp;
+ }
+
+ // now stack the files, some of which may be from the previous stack iteration
+ int i = 0;
+ while (i < Size())
+ {
+ CFileItemPtr item1 = Get(i);
+
+ // skip folders, nfo files, playlists
+ if (item1->m_bIsFolder || item1->IsParentFolder() || item1->IsNFO() || item1->IsPlayList())
+ {
+ // increment index
+ i++;
+ continue;
+ }
+
+ int64_t size = 0;
+ size_t offset = 0;
+ std::string stackName;
+ std::string file1;
+ std::string filePath;
+ std::vector<int> stack;
+ VECCREGEXP::iterator expr = stackRegExps.begin();
+
+ URIUtils::Split(item1->GetPath(), filePath, file1);
+ if (URIUtils::HasEncodedFilename(CURL(filePath)))
+ file1 = CURL::Decode(file1);
+
+ int j;
+ while (expr != stackRegExps.end())
+ {
+ if (expr->RegFind(file1, offset) != -1)
+ {
+ std::string Title1 = expr->GetMatch(1), Volume1 = expr->GetMatch(2),
+ Ignore1 = expr->GetMatch(3), Extension1 = expr->GetMatch(4);
+ if (offset)
+ Title1 = file1.substr(0, expr->GetSubStart(2));
+ j = i + 1;
+ while (j < Size())
+ {
+ CFileItemPtr item2 = Get(j);
+
+ // skip folders, nfo files, playlists
+ if (item2->m_bIsFolder || item2->IsParentFolder() || item2->IsNFO() ||
+ item2->IsPlayList())
+ {
+ // increment index
+ j++;
+ continue;
+ }
+
+ std::string file2, filePath2;
+ URIUtils::Split(item2->GetPath(), filePath2, file2);
+ if (URIUtils::HasEncodedFilename(CURL(filePath2)))
+ file2 = CURL::Decode(file2);
+
+ if (expr->RegFind(file2, offset) != -1)
+ {
+ std::string Title2 = expr->GetMatch(1), Volume2 = expr->GetMatch(2),
+ Ignore2 = expr->GetMatch(3), Extension2 = expr->GetMatch(4);
+ if (offset)
+ Title2 = file2.substr(0, expr->GetSubStart(2));
+ if (StringUtils::EqualsNoCase(Title1, Title2))
+ {
+ if (!StringUtils::EqualsNoCase(Volume1, Volume2))
+ {
+ if (StringUtils::EqualsNoCase(Ignore1, Ignore2) &&
+ StringUtils::EqualsNoCase(Extension1, Extension2))
+ {
+ if (stack.empty())
+ {
+ stackName = Title1 + Ignore1 + Extension1;
+ stack.push_back(i);
+ size += item1->m_dwSize;
+ }
+ stack.push_back(j);
+ size += item2->m_dwSize;
+ }
+ else // Sequel
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ }
+ else if (!StringUtils::EqualsNoCase(Ignore1,
+ Ignore2)) // False positive, try again with offset
+ {
+ offset = expr->GetSubStart(3);
+ break;
+ }
+ else // Extension mismatch
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ }
+ else // Title mismatch
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ }
+ else // No match 2, next expression
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ j++;
+ }
+ if (j == Size())
+ expr = stackRegExps.end();
+ }
+ else // No match 1
+ {
+ offset = 0;
+ ++expr;
+ }
+ if (stack.size() > 1)
+ {
+ // have a stack, remove the items and add the stacked item
+ // dont actually stack a multipart rar set, just remove all items but the first
+ std::string stackPath;
+ if (Get(stack[0])->IsRAR())
+ stackPath = Get(stack[0])->GetPath();
+ else
+ {
+ CStackDirectory dir;
+ stackPath = dir.ConstructStackPath(*this, stack);
+ }
+ item1->SetPath(stackPath);
+ // clean up list
+ for (unsigned k = 1; k < stack.size(); k++)
+ Remove(i + 1);
+ // item->m_bIsFolder = true; // don't treat stacked files as folders
+ // the label may be in a different char set from the filename (eg over smb
+ // the label is converted from utf8, but the filename is not)
+ if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_FILELISTS_SHOWEXTENSIONS))
+ URIUtils::RemoveExtension(stackName);
+
+ item1->SetLabel(stackName);
+ item1->m_dwSize = size;
+ break;
+ }
+ }
+ i++;
+ }
+}
+
+bool CFileItemList::Load(int windowID)
+{
+ CFile file;
+ auto path = GetDiscFileCache(windowID);
+ try
+ {
+ if (file.Open(path))
+ {
+ CArchive ar(&file, CArchive::load);
+ ar >> *this;
+ CLog::Log(LOGDEBUG, "Loading items: {}, directory: {} sort method: {}, ascending: {}", Size(),
+ CURL::GetRedacted(GetPath()), m_sortDescription.sortBy,
+ m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
+ ar.Close();
+ file.Close();
+ return true;
+ }
+ }
+ catch (const std::out_of_range&)
+ {
+ CLog::Log(LOGERROR, "Corrupt archive: {}", CURL::GetRedacted(path));
+ }
+
+ return false;
+}
+
+bool CFileItemList::Save(int windowID)
+{
+ int iSize = Size();
+ if (iSize <= 0)
+ return false;
+
+ CLog::Log(LOGDEBUG, "Saving fileitems [{}]", CURL::GetRedacted(GetPath()));
+
+ CFile file;
+ std::string cachefile = GetDiscFileCache(windowID);
+ if (file.OpenForWrite(cachefile, true)) // overwrite always
+ {
+ // Before caching save simplified cache file name in every item so the cache file can be
+ // identifed and removed if the item is updated. List path and options (used for file
+ // name when list cached) can not be accurately derived from item path.
+ StringUtils::Replace(cachefile, "special://temp/archive_cache/", "");
+ StringUtils::Replace(cachefile, ".fi", "");
+ for (const auto& item : m_items)
+ item->SetProperty("cachefilename", cachefile);
+
+ CArchive ar(&file, CArchive::store);
+ ar << *this;
+ CLog::Log(LOGDEBUG, " -- items: {}, sort method: {}, ascending: {}", iSize,
+ m_sortDescription.sortBy,
+ m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
+ ar.Close();
+ file.Close();
+ return true;
+ }
+
+ return false;
+}
+
+void CFileItemList::RemoveDiscCache(int windowID) const
+{
+ RemoveDiscCache(GetDiscFileCache(windowID));
+}
+
+void CFileItemList::RemoveDiscCache(const std::string& cacheFile) const
+{
+ if (CFile::Exists(cacheFile))
+ {
+ CLog::Log(LOGDEBUG, "Clearing cached fileitems [{}]", CURL::GetRedacted(GetPath()));
+ CFile::Delete(cacheFile);
+ }
+}
+
+void CFileItemList::RemoveDiscCacheCRC(const std::string& crc) const
+{
+ std::string cachefile = StringUtils::Format("special://temp/archive_cache/{}.fi", crc);
+ RemoveDiscCache(cachefile);
+}
+
+std::string CFileItemList::GetDiscFileCache(int windowID) const
+{
+ std::string strPath(GetPath());
+ URIUtils::RemoveSlashAtEnd(strPath);
+
+ uint32_t crc = Crc32::ComputeFromLowerCase(strPath);
+
+ if (IsCDDA() || IsOnDVD())
+ return StringUtils::Format("special://temp/archive_cache/r-{:08x}.fi", crc);
+
+ if (IsMusicDb())
+ return StringUtils::Format("special://temp/archive_cache/mdb-{:08x}.fi", crc);
+
+ if (VIDEO::IsVideoDb(*this))
+ return StringUtils::Format("special://temp/archive_cache/vdb-{:08x}.fi", crc);
+
+ if (IsSmartPlayList())
+ return StringUtils::Format("special://temp/archive_cache/sp-{:08x}.fi", crc);
+
+ if (windowID)
+ return StringUtils::Format("special://temp/archive_cache/{}-{:08x}.fi", windowID, crc);
+
+ return StringUtils::Format("special://temp/archive_cache/{:08x}.fi", crc);
+}
+
+bool CFileItemList::AlwaysCache() const
+{
+ // some database folders are always cached
+ if (IsMusicDb())
+ return CMusicDatabaseDirectory::CanCache(GetPath());
+ if (VIDEO::IsVideoDb(*this))
+ return CVideoDatabaseDirectory::CanCache(GetPath());
+ if (IsEPG())
+ return true; // always cache
+ return false;
+}
+
+void CFileItemList::Swap(unsigned int item1, unsigned int item2)
+{
+ if (item1 != item2 && item1 < m_items.size() && item2 < m_items.size())
+ std::swap(m_items[item1], m_items[item2]);
+}
+
+bool CFileItemList::UpdateItem(const CFileItem* item)
+{
+ if (!item)
+ return false;
+
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->IsSamePath(item))
+ {
+ pItem->UpdateInfo(*item);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CFileItemList::AddSortMethod(SortBy sortBy,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks,
+ SortAttribute sortAttributes /* = SortAttributeNone */)
+{
+ AddSortMethod(sortBy, sortAttributes, buttonLabel, labelMasks);
+}
+
+void CFileItemList::AddSortMethod(SortBy sortBy,
+ SortAttribute sortAttributes,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks)
+{
+ SortDescription sorting;
+ sorting.sortBy = sortBy;
+ sorting.sortAttributes = sortAttributes;
+
+ AddSortMethod(sorting, buttonLabel, labelMasks);
+}
+
+void CFileItemList::AddSortMethod(SortDescription sortDescription,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks)
+{
+ GUIViewSortDetails sort;
+ sort.m_sortDescription = sortDescription;
+ sort.m_buttonLabel = buttonLabel;
+ sort.m_labelMasks = labelMasks;
+
+ m_sortDetails.push_back(sort);
+}
+
+void CFileItemList::SetReplaceListing(bool replace)
+{
+ m_replaceListing = replace;
+}
+
+void CFileItemList::ClearSortState()
+{
+ m_sortDescription.sortBy = SortByNone;
+ m_sortDescription.sortOrder = SortOrderNone;
+ m_sortDescription.sortAttributes = SortAttributeNone;
+}
diff --git a/xbmc/FileItemList.h b/xbmc/FileItemList.h
new file mode 100644
index 0000000000..5f04f179d2
--- /dev/null
+++ b/xbmc/FileItemList.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+/*!
+ \file FileItemList.h
+ \brief
+ */
+
+#include "FileItem.h"
+
+/*!
+ \brief Represents a list of files
+ \sa CFileItemList, CFileItem
+ */
+class CFileItemList : public CFileItem
+{
+public:
+ enum CACHE_TYPE
+ {
+ CACHE_NEVER = 0,
+ CACHE_IF_SLOW,
+ CACHE_ALWAYS
+ };
+
+ CFileItemList();
+ explicit CFileItemList(const std::string& strPath);
+ ~CFileItemList() override;
+ void Archive(CArchive& ar) override;
+ CFileItemPtr operator[](int iItem);
+ const CFileItemPtr operator[](int iItem) const;
+ CFileItemPtr operator[](const std::string& strPath);
+ const CFileItemPtr operator[](const std::string& strPath) const;
+ void Clear();
+ void ClearItems();
+ void Add(CFileItemPtr item);
+ void Add(CFileItem&& item);
+ void AddFront(const CFileItemPtr& pItem, int itemPosition);
+ void Remove(CFileItem* pItem);
+ void Remove(int iItem);
+ CFileItemPtr Get(int iItem) const;
+ const VECFILEITEMS& GetList() const { return m_items; }
+ CFileItemPtr Get(const std::string& strPath) const;
+ int Size() const;
+ bool IsEmpty() const;
+ void Append(const CFileItemList& itemlist);
+ void Assign(const CFileItemList& itemlist, bool append = false);
+ bool Copy(const CFileItemList& item, bool copyItems = true);
+ void Reserve(size_t iCount);
+ void Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes = SortAttributeNone);
+ /* \brief Sorts the items based on the given sorting options
+
+ In contrast to Sort (see above) this does not change the internal
+ state by storing the sorting method and order used and therefore
+ will always execute the sorting even if the list of items has
+ already been sorted with the same options before.
+ */
+ void Sort(SortDescription sortDescription);
+ void Randomize();
+ void FillInDefaultIcons();
+ int GetFolderCount() const;
+ int GetFileCount() const;
+ int GetSelectedCount() const;
+ int GetObjectCount() const;
+ void FilterCueItems();
+ void RemoveExtensions();
+ void SetIgnoreURLOptions(bool ignoreURLOptions);
+ void SetFastLookup(bool fastLookup);
+ bool Contains(const std::string& fileName) const;
+ bool GetFastLookup() const { return m_fastLookup; }
+
+ /*! \brief stack a CFileItemList
+ By default we stack all items (files and folders) in a CFileItemList
+ \param stackFiles whether to stack all items or just collapse folders (defaults to true)
+ \sa StackFiles,StackFolders
+ */
+ void Stack(bool stackFiles = true);
+
+ SortOrder GetSortOrder() const { return m_sortDescription.sortOrder; }
+ SortBy GetSortMethod() const { return m_sortDescription.sortBy; }
+ void SetSortOrder(SortOrder sortOrder) { m_sortDescription.sortOrder = sortOrder; }
+ void SetSortMethod(SortBy sortBy) { m_sortDescription.sortBy = sortBy; }
+
+ /*! \brief load a CFileItemList out of the cache
+
+ The file list may be cached based on which window we're viewing in, as different
+ windows will be listing different portions of the same URL (eg viewing music files
+ versus viewing video files)
+
+ \param windowID id of the window that's loading this list (defaults to 0)
+ \return true if we loaded from the cache, false otherwise.
+ \sa Save,RemoveDiscCache
+ */
+ bool Load(int windowID = 0);
+
+ /*! \brief save a CFileItemList to the cache
+
+ The file list may be cached based on which window we're viewing in, as different
+ windows will be listing different portions of the same URL (eg viewing music files
+ versus viewing video files)
+
+ \param windowID id of the window that's saving this list (defaults to 0)
+ \return true if successful, false otherwise.
+ \sa Load,RemoveDiscCache
+ */
+ bool Save(int windowID = 0);
+ void SetCacheToDisc(CACHE_TYPE cacheToDisc) { m_cacheToDisc = cacheToDisc; }
+ bool CacheToDiscAlways() const { return m_cacheToDisc == CACHE_ALWAYS; }
+ bool CacheToDiscIfSlow() const { return m_cacheToDisc == CACHE_IF_SLOW; }
+ /*! \brief remove a previously cached CFileItemList from the cache
+
+ The file list may be cached based on which window we're viewing in, as different
+ windows will be listing different portions of the same URL (eg viewing music files
+ versus viewing video files)
+
+ \param windowID id of the window whose cache we which to remove (defaults to 0)
+ \sa Save,Load
+ */
+ void RemoveDiscCache(int windowID = 0) const;
+ void RemoveDiscCache(const std::string& cachefile) const;
+ void RemoveDiscCacheCRC(const std::string& crc) const;
+ bool AlwaysCache() const;
+
+ void Swap(unsigned int item1, unsigned int item2);
+
+ /*! \brief Update an item in the item list
+ \param item the new item, which we match based on path to an existing item in the list
+ \return true if the item exists in the list (and was thus updated), false otherwise.
+ */
+ bool UpdateItem(const CFileItem* item);
+
+ void AddSortMethod(SortBy sortBy,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks,
+ SortAttribute sortAttributes = SortAttributeNone);
+ void AddSortMethod(SortBy sortBy,
+ SortAttribute sortAttributes,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks);
+ void AddSortMethod(SortDescription sortDescription,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks);
+ bool HasSortDetails() const { return m_sortDetails.size() != 0; }
+ const std::vector<GUIViewSortDetails>& GetSortDetails() const { return m_sortDetails; }
+
+ /*! \brief Specify whether this list should be sorted with folders separate from files
+ By default we sort with folders listed (and sorted separately) except for those sort modes
+ which should be explicitly sorted with folders interleaved with files (eg SORT_METHOD_FILES).
+ With this set the folder state will be ignored, allowing folders and files to sort interleaved.
+ \param sort whether to ignore the folder state.
+ */
+ void SetSortIgnoreFolders(bool sort) { m_sortIgnoreFolders = sort; }
+ bool GetReplaceListing() const { return m_replaceListing; }
+ void SetReplaceListing(bool replace);
+ void SetContent(const std::string& content) { m_content = content; }
+ const std::string& GetContent() const { return m_content; }
+
+ void ClearSortState();
+
+ VECFILEITEMS::iterator begin() { return m_items.begin(); }
+ VECFILEITEMS::iterator end() { return m_items.end(); }
+ VECFILEITEMS::iterator erase(VECFILEITEMS::iterator first, VECFILEITEMS::iterator last);
+ VECFILEITEMS::const_iterator begin() const { return m_items.begin(); }
+ VECFILEITEMS::const_iterator end() const { return m_items.end(); }
+ VECFILEITEMS::const_iterator cbegin() const { return m_items.cbegin(); }
+ VECFILEITEMS::const_iterator cend() const { return m_items.cend(); }
+ std::reverse_iterator<VECFILEITEMS::const_iterator> rbegin() const { return m_items.rbegin(); }
+ std::reverse_iterator<VECFILEITEMS::const_iterator> rend() const { return m_items.rend(); }
+
+private:
+ void Sort(FILEITEMLISTCOMPARISONFUNC func);
+ void FillSortFields(FILEITEMFILLFUNC func);
+ std::string GetDiscFileCache(int windowID) const;
+
+ /*!
+ \brief stack files in a CFileItemList
+ \sa Stack
+ */
+ void StackFiles();
+
+ /*!
+ \brief stack folders in a CFileItemList
+ \sa Stack
+ */
+ void StackFolders();
+
+ VECFILEITEMS m_items;
+ MAPFILEITEMS m_map;
+ bool m_ignoreURLOptions = false;
+ bool m_fastLookup = false;
+ SortDescription m_sortDescription;
+ bool m_sortIgnoreFolders = false;
+ CACHE_TYPE m_cacheToDisc = CACHE_IF_SLOW;
+ bool m_replaceListing = false;
+ std::string m_content;
+
+ std::vector<GUIViewSortDetails> m_sortDetails;
+
+ mutable CCriticalSection m_lock;
+};
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
index 5a0c79d609..4a508418ef 100644
--- a/xbmc/GUIInfoManager.cpp
+++ b/xbmc/GUIInfoManager.cpp
@@ -1411,6 +1411,14 @@ const infomap weather[] = {{ "isfetched", WEATHER_IS_FETCHED },
/// @return **True** if Kodi is running on an android device.
/// <p>
/// }
+/// \table_row3{ <b>`System.Platform.WebOS`</b>,
+/// \anchor System_PlatformWebOS
+/// _boolean_,
+/// @return **True** if Kodi is running on a WebOS device.
+/// <p><hr>
+/// @skinning_v22 **[New Boolean Condition]** \link System_PlatformWebOS
+/// `System.Platform.WebOS`\endlink <p>
+/// }
/// \table_row3{ <b>`System.CanPowerDown`</b>,
/// \anchor System_CanPowerDown
/// _boolean_,
@@ -10561,6 +10569,8 @@ int CGUIInfoManager::TranslateSingleString(const std::string &strCondition, bool
return SYSTEM_PLATFORM_DARWIN_TVOS;
else if (platform == "android")
return SYSTEM_PLATFORM_ANDROID;
+ else if (platform == "webos")
+ return SYSTEM_PLATFORM_WEBOS;
}
if (info[0].name == "musicplayer")
{ //! @todo these two don't allow duration(foo) and also don't allow more than this number of levels...
diff --git a/xbmc/NfoFile.cpp b/xbmc/NfoFile.cpp
index 2a11da2c17..f74d0efd20 100644
--- a/xbmc/NfoFile.cpp
+++ b/xbmc/NfoFile.cpp
@@ -12,6 +12,7 @@
#include "NfoFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
#include "addons/AddonSystemSettings.h"
diff --git a/xbmc/PartyModeManager.cpp b/xbmc/PartyModeManager.cpp
index 829a9191f5..dd74bad29e 100644
--- a/xbmc/PartyModeManager.cpp
+++ b/xbmc/PartyModeManager.cpp
@@ -9,6 +9,7 @@
#include "PartyModeManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
diff --git a/xbmc/PlayListPlayer.cpp b/xbmc/PlayListPlayer.cpp
index f526f0ae5e..23185d2d42 100644
--- a/xbmc/PlayListPlayer.cpp
+++ b/xbmc/PlayListPlayer.cpp
@@ -9,6 +9,7 @@
#include "PlayListPlayer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "ServiceBroker.h"
@@ -265,7 +266,9 @@ bool CPlayListPlayer::PlayItemIdx(int itemIdx)
return Play();
}
-bool CPlayListPlayer::Play(const CFileItemPtr& pItem, const std::string& player)
+bool CPlayListPlayer::Play(const CFileItemPtr& pItem,
+ const std::string& player,
+ bool forceSelection /* = false */)
{
Id playlistId;
bool isVideo{IsVideo(*pItem)};
@@ -303,13 +306,14 @@ bool CPlayListPlayer::Play(const CFileItemPtr& pItem, const std::string& player)
SetCurrentPlaylist(playlistId);
Add(playlistId, pItem);
- return Play(0, player);
+ return Play(0, player, false, false, forceSelection);
}
bool CPlayListPlayer::Play(int iSong,
const std::string& player,
bool bAutoPlay /* = false */,
- bool bPlayPrevious /* = false */)
+ bool bPlayPrevious /* = false */,
+ bool forceSelection /* = false */)
{
if (m_iCurrentPlayList == TYPE_NONE)
return false;
@@ -341,7 +345,7 @@ bool CPlayListPlayer::Play(int iSong,
m_bPlaybackStarted = false;
const auto playAttempt = std::chrono::steady_clock::now();
- bool ret = g_application.PlayFile(*item, player, bAutoPlay);
+ bool ret = g_application.PlayFile(*item, player, bAutoPlay, forceSelection);
if (!ret)
{
CLog::Log(LOGERROR, "Playlist Player: skipping unplayable item: {}, path [{}]", m_iCurrentSong,
diff --git a/xbmc/PlayListPlayer.h b/xbmc/PlayListPlayer.h
index 961aaf28d4..f17abf6280 100644
--- a/xbmc/PlayListPlayer.h
+++ b/xbmc/PlayListPlayer.h
@@ -55,19 +55,22 @@ public:
* \brief Creates a new playlist for an item and starts playing it
* \param pItem The item to play.
* \param player The player name.
+ * \param forceSelection for Blurays, force simple menu to change playlist (default to false)
* \return True if has success, otherwise false.
*/
- bool Play(const CFileItemPtr& pItem, const std::string& player);
+ bool Play(const CFileItemPtr& pItem, const std::string& player, bool forceSelection = false);
/*! \brief Start playing a particular entry in the current playlist
\param index the index of the item to play. This value is modified to ensure it lies within the current playlist.
\param replace whether this item should replace the currently playing item. See CApplication::PlayFile (defaults to false).
\param playPreviousOnFail whether to go back to the previous item if playback fails (default to false)
+ \param forceSelection for Blurays, force simple menu to change playlist (default to false)
*/
bool Play(int index,
const std::string& player,
bool replace = false,
- bool playPreviousOnFail = false);
+ bool playPreviousOnFail = false,
+ bool forceSelection = false);
/*! \brief Returns the index of the current item in active playlist.
\return Current item in the active playlist.
diff --git a/xbmc/URL.cpp b/xbmc/URL.cpp
index 99b661e36f..073d1104e0 100644
--- a/xbmc/URL.cpp
+++ b/xbmc/URL.cpp
@@ -7,15 +7,17 @@
*/
#include "URL.h"
-#include "utils/log.h"
-#include "utils/URIUtils.h"
-#include "utils/StringUtils.h"
+
+#include "FileItem.h"
+#include "FileItemList.h"
+#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/File.h"
-#include "FileItem.h"
#include "filesystem/StackDirectory.h"
#include "network/Network.h"
-#include "ServiceBroker.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "utils/log.h"
#ifndef TARGET_POSIX
#include <sys\stat.h>
#endif
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp
index 2922b66974..7c69b56425 100644
--- a/xbmc/addons/AddonManager.cpp
+++ b/xbmc/addons/AddonManager.cpp
@@ -10,6 +10,7 @@
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
#include "addons/AddonBuilder.h"
diff --git a/xbmc/addons/AddonManager.h b/xbmc/addons/AddonManager.h
index 10668125c0..fd7ee70f66 100644
--- a/xbmc/addons/AddonManager.h
+++ b/xbmc/addons/AddonManager.h
@@ -16,6 +16,7 @@
#include <mutex>
#include <set>
#include <string>
+#include <utility>
#include <vector>
namespace ADDON
@@ -37,10 +38,10 @@ using ADDON_INFO_LIST = std::map<std::string, AddonInfoPtr>;
class IAddon;
using AddonPtr = std::shared_ptr<IAddon>;
+using AddonWithUpdate = std::pair<std::shared_ptr<IAddon>, std::shared_ptr<IAddon>>;
using VECADDONS = std::vector<AddonPtr>;
struct AddonEvent;
-struct AddonWithUpdate;
struct DependencyInfo;
struct RepositoryDirInfo;
diff --git a/xbmc/addons/AddonRepos.cpp b/xbmc/addons/AddonRepos.cpp
index 5455ca4487..362f051b97 100644
--- a/xbmc/addons/AddonRepos.cpp
+++ b/xbmc/addons/AddonRepos.cpp
@@ -122,20 +122,16 @@ bool CAddonRepos::LoadAddonsFromDatabase(const std::string& addonId,
{
if (m_addonMgr.IsCompatible(addon))
{
- m_addonsByRepoMap[addon->Origin()].insert({addon->ID(), addon});
+ m_addonsByRepoMap[addon->Origin()].emplace(addon->ID(), addon);
}
}
- for (const auto& repo : m_addonsByRepoMap)
+ for (const auto& [repoId, addonsPerRepo] : m_addonsByRepoMap)
{
- CLog::LogFC(LOGDEBUG, LOGADDONS, "{} - {} addon(s) loaded", repo.first, repo.second.size());
+ CLog::LogFC(LOGDEBUG, LOGADDONS, "{} - {} addon(s) loaded", repoId, addonsPerRepo.size());
- const auto& addonsPerRepo = repo.second;
-
- for (const auto& addonMapEntry : addonsPerRepo)
+ for (const auto& [addonId, addonToAdd] : addonsPerRepo)
{
- const auto& addonToAdd = addonMapEntry.second;
-
if (IsFromOfficialRepo(addonToAdd, CheckAddonPath::CHOICE_YES))
{
AddAddonIfLatest(addonToAdd, m_latestOfficialVersions);
@@ -146,7 +142,7 @@ bool CAddonRepos::LoadAddonsFromDatabase(const std::string& addonId,
}
// add to latestVersionsByRepo
- AddAddonIfLatest(repo.first, addonToAdd, m_latestVersionsByRepo);
+ AddAddonIfLatest(repoId, addonToAdd, m_latestVersionsByRepo);
}
}
@@ -156,8 +152,8 @@ bool CAddonRepos::LoadAddonsFromDatabase(const std::string& addonId,
void CAddonRepos::AddAddonIfLatest(const std::shared_ptr<IAddon>& addonToAdd,
std::map<std::string, std::shared_ptr<IAddon>>& map) const
{
- const auto& latestKnown = map.find(addonToAdd->ID());
- if (latestKnown == map.end() || addonToAdd->Version() > latestKnown->second->Version())
+ const auto latestKnownIt = map.find(addonToAdd->ID());
+ if (latestKnownIt == map.end() || addonToAdd->Version() > latestKnownIt->second->Version())
map[addonToAdd->ID()] = addonToAdd;
}
@@ -166,21 +162,23 @@ void CAddonRepos::AddAddonIfLatest(
const std::shared_ptr<IAddon>& addonToAdd,
std::map<std::string, std::map<std::string, std::shared_ptr<IAddon>>>& map) const
{
- const auto& latestVersionByRepo = map.find(repoId);
+ bool doInsert{true};
- if (latestVersionByRepo == map.end()) // repo not found
- {
- map[repoId].insert({addonToAdd->ID(), addonToAdd});
- }
- else
+ const auto latestVersionByRepoIt = map.find(repoId);
+ if (latestVersionByRepoIt != map.end()) // we already have this repository in the outer map
{
- const auto& latestVersionEntryByRepo = latestVersionByRepo->second;
- const auto& latestKnown = latestVersionEntryByRepo.find(addonToAdd->ID());
+ const auto& latestVersionEntryByRepo = latestVersionByRepoIt->second;
+ const auto latestKnownIt = latestVersionEntryByRepo.find(addonToAdd->ID());
- if (latestKnown == latestVersionEntryByRepo.end() ||
- addonToAdd->Version() > latestKnown->second->Version())
- map[repoId][addonToAdd->ID()] = addonToAdd;
+ if (latestKnownIt != latestVersionEntryByRepo.end() &&
+ addonToAdd->Version() <= latestKnownIt->second->Version())
+ {
+ doInsert = false;
+ }
}
+
+ if (doInsert)
+ map[repoId][addonToAdd->ID()] = addonToAdd;
}
void CAddonRepos::BuildUpdateOrOutdatedList(const std::vector<std::shared_ptr<IAddon>>& installed,
@@ -212,7 +210,7 @@ void CAddonRepos::BuildAddonsWithUpdateList(
{
if (DoAddonUpdateCheck(addon, update))
{
- addonsWithUpdate.insert({addon->ID(), {addon, update}});
+ addonsWithUpdate.try_emplace(addon->ID(), addon, update);
}
}
}
@@ -253,10 +251,10 @@ bool CAddonRepos::DoAddonUpdateCheck(const std::shared_ptr<IAddon>& addon,
else
{
// ...we check for updates in the origin repo only
- const auto& repoEntry = m_latestVersionsByRepo.find(addon->Origin());
- if (repoEntry != m_latestVersionsByRepo.end())
+ const auto repoEntryIt = m_latestVersionsByRepo.find(addon->Origin());
+ if (repoEntryIt != m_latestVersionsByRepo.end())
{
- if (!FindAddonAndCheckForUpdate(addon, repoEntry->second, update))
+ if (!FindAddonAndCheckForUpdate(addon, repoEntryIt->second, update))
{
return false;
}
@@ -280,14 +278,14 @@ bool CAddonRepos::FindAddonAndCheckForUpdate(
const std::map<std::string, std::shared_ptr<IAddon>>& map,
std::shared_ptr<IAddon>& update) const
{
- const auto& remote = map.find(addonToCheck->ID());
- if (remote != map.end()) // is addon in the desired map?
+ const auto remoteIt = map.find(addonToCheck->ID());
+ if (remoteIt != map.end()) // is addon in the desired map?
{
- if ((remote->second->Version() > addonToCheck->Version()) ||
+ if ((remoteIt->second->Version() > addonToCheck->Version()) ||
m_addonMgr.IsAddonDisabledWithReason(addonToCheck->ID(), AddonDisabledReason::INCOMPATIBLE))
{
// return addon update
- update = remote->second;
+ update = remoteIt->second;
return true; // update found
}
}
@@ -300,10 +298,10 @@ bool CAddonRepos::GetLatestVersionByMap(const std::string& addonId,
const std::map<std::string, std::shared_ptr<IAddon>>& map,
std::shared_ptr<IAddon>& addon) const
{
- const auto& remote = map.find(addonId);
- if (remote != map.end()) // is addon in the desired map?
+ const auto remoteIt = map.find(addonId);
+ if (remoteIt != map.end()) // is addon in the desired map?
{
- addon = remote->second;
+ addon = remoteIt->second;
return true;
}
@@ -356,14 +354,15 @@ void CAddonRepos::GetLatestAddonVersions(std::vector<std::shared_ptr<IAddon>>& a
// then we insert private addon versions if they don't exist in the official map
// or installation from ANY_REPOSITORY is allowed and the private version is higher
- for (const auto& privateVersion : m_latestPrivateVersions)
+ for (const auto& [privateVersionId, privateVersion] : m_latestPrivateVersions)
{
- const auto& officialVersion = m_latestOfficialVersions.find(privateVersion.first);
- if (officialVersion == m_latestOfficialVersions.end() ||
+ const auto officialVersionIt = m_latestOfficialVersions.find(privateVersionId);
+
+ if (officialVersionIt == m_latestOfficialVersions.end() ||
(updateMode == AddonRepoUpdateMode::ANY_REPOSITORY &&
- privateVersion.second->Version() > officialVersion->second->Version()))
+ privateVersion->Version() > officialVersionIt->second->Version()))
{
- addonList.emplace_back(privateVersion.second);
+ addonList.emplace_back(privateVersion);
}
}
}
@@ -390,18 +389,18 @@ void CAddonRepos::GetLatestAddonVersionsFromAllRepos(
// so we need to filter them out
if (std::none_of(officialRepoInfos.begin(), officialRepoInfos.end(),
- [&](const ADDON::RepoInfo& officialRepo) {
- return repo.first == officialRepo.m_repoId;
- }))
+ [&repo](const ADDON::RepoInfo& officialRepo)
+ { return repo.first == officialRepo.m_repoId; }))
{
- for (const auto& latestAddon : repo.second)
+ for (const auto& [latestAddonId, latestAddon] : repo.second)
{
- const auto& officialVersion = m_latestOfficialVersions.find(latestAddon.first);
- if (officialVersion == m_latestOfficialVersions.end() ||
+ const auto officialVersionIt = m_latestOfficialVersions.find(latestAddonId);
+
+ if (officialVersionIt == m_latestOfficialVersions.end() ||
(updateMode == AddonRepoUpdateMode::ANY_REPOSITORY &&
- latestAddon.second->Version() > officialVersion->second->Version()))
+ latestAddon->Version() > officialVersionIt->second->Version()))
{
- addonList.emplace_back(latestAddon.second);
+ addonList.emplace_back(latestAddon);
}
}
}
@@ -469,10 +468,10 @@ bool CAddonRepos::FindDependencyByParentRepo(const std::string& dependsId,
const std::string& parentRepoId,
std::shared_ptr<IAddon>& dependencyToInstall) const
{
- const auto& repoEntry = m_latestVersionsByRepo.find(parentRepoId);
- if (repoEntry != m_latestVersionsByRepo.end())
+ const auto repoEntryIt = m_latestVersionsByRepo.find(parentRepoId);
+ if (repoEntryIt != m_latestVersionsByRepo.end())
{
- if (GetLatestVersionByMap(dependsId, repoEntry->second, dependencyToInstall))
+ if (GetLatestVersionByMap(dependsId, repoEntryIt->second, dependencyToInstall))
return true;
}
diff --git a/xbmc/addons/AddonRepos.h b/xbmc/addons/AddonRepos.h
index bb9be3473c..4284674f01 100644
--- a/xbmc/addons/AddonRepos.h
+++ b/xbmc/addons/AddonRepos.h
@@ -13,6 +13,7 @@
#include <map>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
namespace ADDON
@@ -30,14 +31,7 @@ enum class CheckAddonPath
CHOICE_NO = false,
};
-/**
- * Struct - CAddonWithUpdate
- */
-struct AddonWithUpdate
-{
- std::shared_ptr<IAddon> m_installed;
- std::shared_ptr<IAddon> m_update;
-};
+using AddonWithUpdate = std::pair<std::shared_ptr<IAddon>, std::shared_ptr<IAddon>>;
/**
* Class - CAddonRepos
diff --git a/xbmc/addons/FilesystemInstaller.cpp b/xbmc/addons/FilesystemInstaller.cpp
index 0f7b32de64..f6dd80131a 100644
--- a/xbmc/addons/FilesystemInstaller.cpp
+++ b/xbmc/addons/FilesystemInstaller.cpp
@@ -8,6 +8,7 @@
#include "FilesystemInstaller.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "filesystem/File.h"
#include "filesystem/SpecialProtocol.h"
diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp
index 66cedcb969..b759dc84e7 100644
--- a/xbmc/addons/Scraper.cpp
+++ b/xbmc/addons/Scraper.cpp
@@ -9,6 +9,7 @@
#include "Scraper.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/addons/Skin.cpp b/xbmc/addons/Skin.cpp
index a6192d902b..746800776c 100644
--- a/xbmc/addons/Skin.cpp
+++ b/xbmc/addons/Skin.cpp
@@ -9,6 +9,7 @@
#include "Skin.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "addons/addoninfo/AddonType.h"
diff --git a/xbmc/addons/VFSEntry.h b/xbmc/addons/VFSEntry.h
index c11fca05da..414f9593af 100644
--- a/xbmc/addons/VFSEntry.h
+++ b/xbmc/addons/VFSEntry.h
@@ -8,6 +8,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "addons/binary-addons/AddonDll.h"
#include "addons/binary-addons/AddonInstanceHandler.h"
#include "addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h"
diff --git a/xbmc/addons/addoninfo/AddonInfo.cpp b/xbmc/addons/addoninfo/AddonInfo.cpp
index f891e73bc9..0f2f7fba5f 100644
--- a/xbmc/addons/addoninfo/AddonInfo.cpp
+++ b/xbmc/addons/addoninfo/AddonInfo.cpp
@@ -9,6 +9,7 @@
#include "AddonInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/addons/gui/GUIDialogAddonInfo.cpp b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
index 671e55dcf4..172af8b216 100644
--- a/xbmc/addons/gui/GUIDialogAddonInfo.cpp
+++ b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogAddonInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/addons/gui/GUIDialogAddonSettings.cpp b/xbmc/addons/gui/GUIDialogAddonSettings.cpp
index 4830283e4d..60cbaa2a2e 100644
--- a/xbmc/addons/gui/GUIDialogAddonSettings.cpp
+++ b/xbmc/addons/gui/GUIDialogAddonSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogAddonSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
diff --git a/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp b/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp
index 5504f33ecd..7ecb3cbcf8 100644
--- a/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp
+++ b/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateAddonBrowser.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/File.h"
#include "guilib/WindowIDs.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
index f130bacad1..880e784835 100644
--- a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
+++ b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogAddonInfo.h"
#include "GUIUserMessages.h"
#include "LangInfo.h"
diff --git a/xbmc/addons/interfaces/Filesystem.cpp b/xbmc/addons/interfaces/Filesystem.cpp
index c063b48fd6..9f22b67ecc 100644
--- a/xbmc/addons/interfaces/Filesystem.cpp
+++ b/xbmc/addons/interfaces/Filesystem.cpp
@@ -9,6 +9,7 @@
#include "Filesystem.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "Util.h"
#include "addons/binary-addons/AddonDll.h"
#include "filesystem/CurlFile.h"
diff --git a/xbmc/addons/interfaces/gui/Window.cpp b/xbmc/addons/interfaces/gui/Window.cpp
index b817d443a3..831b89fdbd 100644
--- a/xbmc/addons/interfaces/gui/Window.cpp
+++ b/xbmc/addons/interfaces/gui/Window.cpp
@@ -9,6 +9,7 @@
#include "addons/kodi-dev-kit/include/kodi/gui/Window.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUITranslator.h"
#include "General.h"
#include "ServiceBroker.h"
diff --git a/xbmc/addons/settings/AddonSettings.cpp b/xbmc/addons/settings/AddonSettings.cpp
index 2fc9f26fae..b3bd9bb124 100644
--- a/xbmc/addons/settings/AddonSettings.cpp
+++ b/xbmc/addons/settings/AddonSettings.cpp
@@ -9,6 +9,7 @@
#include "AddonSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
diff --git a/xbmc/application/AppParamParser.cpp b/xbmc/application/AppParamParser.cpp
index ca9cd2acef..20b54e7869 100644
--- a/xbmc/application/AppParamParser.cpp
+++ b/xbmc/application/AppParamParser.cpp
@@ -10,6 +10,7 @@
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "application/AppParams.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/application/AppParams.cpp b/xbmc/application/AppParams.cpp
index 97c09e3934..8b174467b4 100644
--- a/xbmc/application/AppParams.cpp
+++ b/xbmc/application/AppParams.cpp
@@ -8,12 +8,14 @@
#include "AppParams.h"
-#include "FileItem.h"
+#include "FileItemList.h"
CAppParams::CAppParams() : m_playlist(std::make_unique<CFileItemList>())
{
}
+CAppParams::~CAppParams() = default;
+
void CAppParams::SetRawArgs(std::vector<std::string> args)
{
m_rawArgs = std::move(args);
diff --git a/xbmc/application/AppParams.h b/xbmc/application/AppParams.h
index 6999249719..12d7aba2b9 100644
--- a/xbmc/application/AppParams.h
+++ b/xbmc/application/AppParams.h
@@ -21,7 +21,7 @@ class CAppParams
{
public:
CAppParams();
- virtual ~CAppParams() = default;
+ virtual ~CAppParams();
int GetLogLevel() const { return m_logLevel; }
void SetLogLevel(int logLevel) { m_logLevel = logLevel; }
diff --git a/xbmc/application/Application.cpp b/xbmc/application/Application.cpp
index 6541a22759..9244fb2040 100644
--- a/xbmc/application/Application.cpp
+++ b/xbmc/application/Application.cpp
@@ -2286,7 +2286,10 @@ bool CApplication::PlayStack(CFileItem& item, bool bRestart)
return PlayFile(selectedStackPart, "", true);
}
-bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRestart)
+bool CApplication::PlayFile(CFileItem item,
+ const std::string& player,
+ bool bRestart /* = false */,
+ bool forceSelection /* = false */)
{
// Ensure the MIME type has been retrieved for http:// and shout:// streams
if (item.GetMimeType().empty())
@@ -2426,7 +2429,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
// a disc image might be Blu-Ray disc
if (!(options.startpercent > 0.0 || options.starttime > 0.0) &&
- (IsBDFile(item) || item.IsDiscImage()))
+ (IsBDFile(item) || item.IsDiscImage() || (IsBlurayPlaylist(item) && forceSelection)))
{
// No video selection when using external or remote players (they handle it if supported)
const bool isSimpleMenuAllowed = [&]()
@@ -2444,7 +2447,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
if (isSimpleMenuAllowed)
{
// Check if we must show the simplified bd menu.
- if (!CGUIDialogSimpleMenu::ShowPlaySelection(item))
+ if (!CGUIDialogSimpleMenu::ShowPlaySelection(item, forceSelection))
return true;
}
}
diff --git a/xbmc/application/Application.h b/xbmc/application/Application.h
index e06df1cc26..d87ad975f9 100644
--- a/xbmc/application/Application.h
+++ b/xbmc/application/Application.h
@@ -125,7 +125,10 @@ public:
PLAYLIST::CPlayList& playlist,
PLAYLIST::Id playlistId,
int track = 0);
- bool PlayFile(CFileItem item, const std::string& player, bool bRestart = false);
+ bool PlayFile(CFileItem item,
+ const std::string& player,
+ bool bRestart = false,
+ bool forceSelection = false);
void StopPlaying();
void Restart(bool bSamePosition = true);
void DelayedPlayerRestart();
diff --git a/xbmc/application/ApplicationSkinHandling.cpp b/xbmc/application/ApplicationSkinHandling.cpp
index bf73f14363..5f916060ac 100644
--- a/xbmc/application/ApplicationSkinHandling.cpp
+++ b/xbmc/application/ApplicationSkinHandling.cpp
@@ -9,6 +9,7 @@
#include "ApplicationSkinHandling.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUILargeTextureManager.h"
#include "GUIUserMessages.h"
diff --git a/xbmc/application/ApplicationStackHelper.cpp b/xbmc/application/ApplicationStackHelper.cpp
index 27b7808a2a..515c52b5aa 100644
--- a/xbmc/application/ApplicationStackHelper.cpp
+++ b/xbmc/application/ApplicationStackHelper.cpp
@@ -9,6 +9,7 @@
#include "ApplicationStackHelper.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "Util.h"
#include "cores/VideoPlayer/DVDFileInfo.h"
diff --git a/xbmc/cdrip/CDDARipper.cpp b/xbmc/cdrip/CDDARipper.cpp
index 41dcc8d5d6..b174c8bbd3 100644
--- a/xbmc/cdrip/CDDARipper.cpp
+++ b/xbmc/cdrip/CDDARipper.cpp
@@ -10,6 +10,7 @@
#include "CDDARipJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
index 4b450ec5cb..ca02e2bafa 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
@@ -218,10 +218,10 @@ bool CAESinkDirectSound::Initialize(AEAudioFormat &format, std::string &device)
m_AvgBytesPerSec = wfxex.Format.nAvgBytesPerSec;
- unsigned int uiFrameCount = (int)(format.m_sampleRate * 0.015); //default to 15ms chunks
+ const unsigned int uiFrameCount = static_cast<int>(format.m_sampleRate * 0.050); // 50ms chunks
m_dwFrameSize = wfxex.Format.nBlockAlign;
m_dwChunkSize = m_dwFrameSize * uiFrameCount;
- m_dwBufferLen = m_dwChunkSize * 12; //180ms total buffer
+ m_dwBufferLen = m_dwChunkSize * 8; // 400ms total buffer
// fill in the secondary sound buffer descriptor
DSBUFFERDESC dsbdesc = {};
diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
index a2084261b1..b86fa65414 100644
--- a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
+++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
@@ -44,6 +44,7 @@
#endif
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp b/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp
index 7864a15261..a6deeddb94 100644
--- a/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp
+++ b/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp
@@ -9,6 +9,7 @@
#include "SavestateDatabase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "SavestateFlatBuffer.h"
#include "URL.h"
#include "XBDateTime.h"
diff --git a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
index 4d40259153..65dfc539de 100644
--- a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
+++ b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
@@ -11,6 +11,7 @@
#include "DVDInputStreams/DVDInputStream.h"
#include "DVDStreamInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/StackDirectory.h"
#include "guilib/Texture.h"
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp
index 1f018617ac..3788295b01 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp
@@ -9,6 +9,7 @@
#include "DVDInputStreamStack.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/File.h"
#include "filesystem/StackDirectory.h"
#include "utils/log.h"
diff --git a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp
index 7ac7ec7e71..a8a5e0e35f 100644
--- a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp
+++ b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp
@@ -9,6 +9,7 @@
#include "DVDSubtitlesLibass.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "cores/VideoPlayer/Interface/TimingConstants.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp
index cf3b31324a..237afacc42 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp
@@ -352,6 +352,11 @@ void COverlayGlyphGLES::Render(SRenderState& state)
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint colLoc = renderSystem->GUIShaderGetCol();
GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
+ GLint matrixUniformLoc = renderSystem->GUIShaderGetMatrix();
+
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
// stack object until VBOs will be used
std::vector<VERTEX> vecVertices(6 * m_vertex.size() / 4);
diff --git a/xbmc/dialogs/GUIDialogColorPicker.cpp b/xbmc/dialogs/GUIDialogColorPicker.cpp
index b4bc59c355..58814de392 100644
--- a/xbmc/dialogs/GUIDialogColorPicker.cpp
+++ b/xbmc/dialogs/GUIDialogColorPicker.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogColorPicker.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/SpecialProtocol.h"
#include "guilib/GUIColorManager.h"
#include "guilib/GUIMessage.h"
diff --git a/xbmc/dialogs/GUIDialogContextMenu.h b/xbmc/dialogs/GUIDialogContextMenu.h
index 9ca6b1f22b..10385bd20e 100644
--- a/xbmc/dialogs/GUIDialogContextMenu.h
+++ b/xbmc/dialogs/GUIDialogContextMenu.h
@@ -88,6 +88,7 @@ enum CONTEXT_BUTTON
CONTEXT_BUTTON_PLAY_NEXT,
CONTEXT_BUTTON_NAVIGATE,
CONTEXT_BUTTON_MANAGE_VIDEOVERSIONS,
+ CONTEXT_BUTTON_CHOOSE_PLAYLIST,
};
class CContextButtons : public std::vector< std::pair<size_t, std::string> >
diff --git a/xbmc/dialogs/GUIDialogFileBrowser.cpp b/xbmc/dialogs/GUIDialogFileBrowser.cpp
index 9181313747..8fecfb62b6 100644
--- a/xbmc/dialogs/GUIDialogFileBrowser.cpp
+++ b/xbmc/dialogs/GUIDialogFileBrowser.cpp
@@ -10,6 +10,7 @@
#include "AutoSwitch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogContextMenu.h"
#include "GUIDialogMediaSource.h"
#include "GUIDialogYesNo.h"
diff --git a/xbmc/dialogs/GUIDialogMediaFilter.cpp b/xbmc/dialogs/GUIDialogMediaFilter.cpp
index 14340c85bb..55b1013967 100644
--- a/xbmc/dialogs/GUIDialogMediaFilter.cpp
+++ b/xbmc/dialogs/GUIDialogMediaFilter.cpp
@@ -10,6 +10,7 @@
#include "DbUrl.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "XBDateTime.h"
diff --git a/xbmc/dialogs/GUIDialogMediaSource.cpp b/xbmc/dialogs/GUIDialogMediaSource.cpp
index 72b80bff53..0afbc2d060 100644
--- a/xbmc/dialogs/GUIDialogMediaSource.cpp
+++ b/xbmc/dialogs/GUIDialogMediaSource.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogMediaSource.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogFileBrowser.h"
#include "GUIDialogYesNo.h"
#include "PasswordManager.h"
diff --git a/xbmc/dialogs/GUIDialogSelect.cpp b/xbmc/dialogs/GUIDialogSelect.cpp
index c6add4bd16..0f99e2765b 100644
--- a/xbmc/dialogs/GUIDialogSelect.cpp
+++ b/xbmc/dialogs/GUIDialogSelect.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/GUIMessage.h"
#include "guilib/LocalizeStrings.h"
#include "input/actions/ActionIDs.h"
diff --git a/xbmc/dialogs/GUIDialogSimpleMenu.cpp b/xbmc/dialogs/GUIDialogSimpleMenu.cpp
index 8fac08b096..2049e2615c 100644
--- a/xbmc/dialogs/GUIDialogSimpleMenu.cpp
+++ b/xbmc/dialogs/GUIDialogSimpleMenu.cpp
@@ -10,6 +10,7 @@
#include "GUIDialogSimpleMenu.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogSelect.h"
#include "ServiceBroker.h"
#include "URL.h"
@@ -28,6 +29,8 @@
#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
+std::string m_savePath;
+
using namespace KODI;
namespace
@@ -51,12 +54,18 @@ protected:
};
}
-
-bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item)
+bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item, bool forceSelection /* = false */)
{
if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_DISC_PLAYBACK) != BD_PLAYBACK_SIMPLE_MENU)
return true;
+ m_savePath = "";
+ if (VIDEO::IsBlurayPlaylist(item) && forceSelection)
+ {
+ m_savePath = item.GetDynPath(); // save for screen refresh later
+ item.SetDynPath(item.GetBlurayPath());
+ }
+
if (VIDEO::IsBDFile(item))
{
std::string root = URIUtils::GetParentPath(item.GetDynPath());
@@ -126,10 +135,11 @@ bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item, const std::string&
if (item_new->m_bIsFolder == false)
{
- std::string original_path = item.GetDynPath();
+ if (m_savePath.empty()) // If not set above (choose playlist selected)
+ m_savePath = item.GetDynPath();
item.SetDynPath(item_new->GetDynPath());
item.SetProperty("get_stream_details_from_player", true);
- item.SetProperty("original_listitem_url", original_path);
+ item.SetProperty("original_listitem_url", m_savePath);
return true;
}
diff --git a/xbmc/dialogs/GUIDialogSimpleMenu.h b/xbmc/dialogs/GUIDialogSimpleMenu.h
index ed476a4d92..bf7ccae980 100644
--- a/xbmc/dialogs/GUIDialogSimpleMenu.h
+++ b/xbmc/dialogs/GUIDialogSimpleMenu.h
@@ -20,7 +20,7 @@ class CGUIDialogSimpleMenu
public:
/*! \brief Show dialog allowing selection of wanted playback item */
- static bool ShowPlaySelection(CFileItem& item);
+ static bool ShowPlaySelection(CFileItem& item, bool forceSelection = false);
static bool ShowPlaySelection(CFileItem& item, const std::string& directory);
protected:
diff --git a/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp b/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
index 98714d38dc..24a0675c40 100644
--- a/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
+++ b/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSmartPlaylistEditor.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogContextMenu.h"
#include "GUIDialogSelect.h"
#include "GUIDialogSmartPlaylistRule.h"
diff --git a/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp b/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
index 671219bc38..9040f48340 100644
--- a/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
+++ b/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSmartPlaylistRule.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogFileBrowser.h"
#include "GUIDialogSelect.h"
#include "ServiceBroker.h"
diff --git a/xbmc/events/windows/GUIViewStateEventLog.cpp b/xbmc/events/windows/GUIViewStateEventLog.cpp
index 1f6dd6654f..8734f12571 100644
--- a/xbmc/events/windows/GUIViewStateEventLog.cpp
+++ b/xbmc/events/windows/GUIViewStateEventLog.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateEventLog.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/WindowIDs.h"
#include "view/ViewState.h"
#include "windowing/GraphicContext.h"
diff --git a/xbmc/events/windows/GUIWindowEventLog.cpp b/xbmc/events/windows/GUIWindowEventLog.cpp
index fdd9a37b00..90e8c29f71 100644
--- a/xbmc/events/windows/GUIWindowEventLog.cpp
+++ b/xbmc/events/windows/GUIWindowEventLog.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowEventLog.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/favourites/FavouritesService.h b/xbmc/favourites/FavouritesService.h
index ccda06253d..468961ecb3 100644
--- a/xbmc/favourites/FavouritesService.h
+++ b/xbmc/favourites/FavouritesService.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "threads/CriticalSection.h"
#include "utils/EventStream.h"
diff --git a/xbmc/favourites/GUIViewStateFavourites.cpp b/xbmc/favourites/GUIViewStateFavourites.cpp
index 7bb5ff1195..3343167b5c 100644
--- a/xbmc/favourites/GUIViewStateFavourites.cpp
+++ b/xbmc/favourites/GUIViewStateFavourites.cpp
@@ -8,7 +8,7 @@
#include "GUIViewStateFavourites.h"
-#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/WindowIDs.h"
CGUIViewStateFavourites::CGUIViewStateFavourites(const CFileItemList& items) : CGUIViewState(items)
diff --git a/xbmc/filesystem/AddonsDirectory.cpp b/xbmc/filesystem/AddonsDirectory.cpp
index 1439ae054b..aba97cae08 100644
--- a/xbmc/filesystem/AddonsDirectory.cpp
+++ b/xbmc/filesystem/AddonsDirectory.cpp
@@ -9,6 +9,7 @@
#include "AddonsDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "addons/AddonDatabase.h"
@@ -789,29 +790,27 @@ void CAddonsDirectory::GenerateAddonListing(const CURL& path,
addon->Version());
bool disabled = CServiceBroker::GetAddonMgr().IsAddonDisabled(addon->ID());
- std::function<bool(bool)> CheckOutdatedOrUpdate = [&](bool checkOutdated) -> bool {
- auto mapEntry = addonsWithUpdate.find(addon->ID());
- if (mapEntry != addonsWithUpdate.end())
- {
- const std::shared_ptr<IAddon>& checkedObject =
- checkOutdated ? mapEntry->second.m_installed : mapEntry->second.m_update;
-
- return (checkedObject->Origin() == addon->Origin() &&
- checkedObject->Version() == addon->Version());
- }
- return false;
- };
-
- bool isUpdate = CheckOutdatedOrUpdate(false); // check if it's an available update
- bool hasUpdate = CheckOutdatedOrUpdate(true); // check if it's an outdated addon
-
+ bool isUpdate{false};
+ bool hasUpdate{false};
std::string validUpdateVersion;
std::string validUpdateOrigin;
- if (hasUpdate)
+
+ auto _ = addonsWithUpdate.find(addon->ID());
+ if (_ != addonsWithUpdate.end())
{
- auto mapEntry = addonsWithUpdate.find(addon->ID());
- validUpdateVersion = mapEntry->second.m_update->Version().asString();
- validUpdateOrigin = mapEntry->second.m_update->Origin();
+ auto [installed, update] = _->second;
+
+ auto CheckAddon = [&addon](const std::shared_ptr<IAddon>& _)
+ { return _->Origin() == addon->Origin() && _->Version() == addon->Version(); };
+
+ isUpdate = CheckAddon(update); // check if listed add-on is update to an installed add-on
+ hasUpdate = CheckAddon(installed); // check if installed add-on has an update available
+
+ if (hasUpdate)
+ {
+ validUpdateVersion = update->Version().asString();
+ validUpdateOrigin = update->Origin();
+ }
}
bool fromOfficialRepo = CAddonRepos::IsFromOfficialRepo(addon, CheckAddonPath::CHOICE_NO);
diff --git a/xbmc/filesystem/AudioBookFileDirectory.cpp b/xbmc/filesystem/AudioBookFileDirectory.cpp
index 4b56c6ccc2..2ca214c74e 100644
--- a/xbmc/filesystem/AudioBookFileDirectory.cpp
+++ b/xbmc/filesystem/AudioBookFileDirectory.cpp
@@ -8,6 +8,7 @@
#include "AudioBookFileDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "TextureDatabase.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/filesystem/BlurayCallback.cpp b/xbmc/filesystem/BlurayCallback.cpp
index 4849eef1a7..72b745381a 100644
--- a/xbmc/filesystem/BlurayCallback.cpp
+++ b/xbmc/filesystem/BlurayCallback.cpp
@@ -9,6 +9,7 @@
#include "BlurayCallback.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "filesystem/File.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/BlurayDirectory.cpp b/xbmc/filesystem/BlurayDirectory.cpp
index b6c339a110..322b662fd9 100644
--- a/xbmc/filesystem/BlurayDirectory.cpp
+++ b/xbmc/filesystem/BlurayDirectory.cpp
@@ -9,6 +9,7 @@
#include "File.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "URL.h"
#include "filesystem/BlurayCallback.h"
diff --git a/xbmc/filesystem/CDDADirectory.cpp b/xbmc/filesystem/CDDADirectory.cpp
index 9b6beaaeea..8520347108 100644
--- a/xbmc/filesystem/CDDADirectory.cpp
+++ b/xbmc/filesystem/CDDADirectory.cpp
@@ -10,6 +10,7 @@
#include "File.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "music/MusicDatabase.h"
#include "storage/MediaManager.h"
diff --git a/xbmc/filesystem/DAVDirectory.cpp b/xbmc/filesystem/DAVDirectory.cpp
index 0a203e7807..08905fca31 100644
--- a/xbmc/filesystem/DAVDirectory.cpp
+++ b/xbmc/filesystem/DAVDirectory.cpp
@@ -12,6 +12,7 @@
#include "DAVCommon.h"
#include "DAVFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/Directorization.h b/xbmc/filesystem/Directorization.h
index f413635e6d..d41c71bae9 100644
--- a/xbmc/filesystem/Directorization.h
+++ b/xbmc/filesystem/Directorization.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/Directory.cpp b/xbmc/filesystem/Directory.cpp
index 8d34c05d08..cfa0fd9b53 100644
--- a/xbmc/filesystem/Directory.cpp
+++ b/xbmc/filesystem/Directory.cpp
@@ -12,6 +12,7 @@
#include "DirectoryFactory.h"
#include "FileDirectoryFactory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PasswordManager.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/filesystem/DirectoryCache.cpp b/xbmc/filesystem/DirectoryCache.cpp
index f3fd1fb7ae..f1053a904b 100644
--- a/xbmc/filesystem/DirectoryCache.cpp
+++ b/xbmc/filesystem/DirectoryCache.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/EventsDirectory.cpp b/xbmc/filesystem/EventsDirectory.cpp
index d21261944b..bc8cfdf0af 100644
--- a/xbmc/filesystem/EventsDirectory.cpp
+++ b/xbmc/filesystem/EventsDirectory.cpp
@@ -10,6 +10,7 @@
#include "EventsDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "events/EventLog.h"
diff --git a/xbmc/filesystem/FTPDirectory.cpp b/xbmc/filesystem/FTPDirectory.cpp
index 46d3d7d748..2b7117a7a8 100644
--- a/xbmc/filesystem/FTPDirectory.cpp
+++ b/xbmc/filesystem/FTPDirectory.cpp
@@ -11,6 +11,7 @@
#include "CurlFile.h"
#include "FTPParse.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/HTTPDirectory.cpp b/xbmc/filesystem/HTTPDirectory.cpp
index 0097b7f15c..1db70696d1 100644
--- a/xbmc/filesystem/HTTPDirectory.cpp
+++ b/xbmc/filesystem/HTTPDirectory.cpp
@@ -10,6 +10,7 @@
#include "CurlFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "settings/AdvancedSettings.h"
diff --git a/xbmc/filesystem/ISO9660Directory.cpp b/xbmc/filesystem/ISO9660Directory.cpp
index 542f12c577..a396b996b0 100644
--- a/xbmc/filesystem/ISO9660Directory.cpp
+++ b/xbmc/filesystem/ISO9660Directory.cpp
@@ -9,6 +9,7 @@
#include "ISO9660Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/LibraryDirectory.cpp b/xbmc/filesystem/LibraryDirectory.cpp
index 8f814950ae..ec5a16bfc0 100644
--- a/xbmc/filesystem/LibraryDirectory.cpp
+++ b/xbmc/filesystem/LibraryDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "SmartPlaylistDirectory.h"
#include "URL.h"
diff --git a/xbmc/filesystem/MultiPathDirectory.cpp b/xbmc/filesystem/MultiPathDirectory.cpp
index 4cdcfcc4ce..b57dd98427 100644
--- a/xbmc/filesystem/MultiPathDirectory.cpp
+++ b/xbmc/filesystem/MultiPathDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory.cpp b/xbmc/filesystem/MusicDatabaseDirectory.cpp
index f998d559f7..0365f86617 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory.cpp
@@ -9,6 +9,7 @@
#include "MusicDatabaseDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MusicDatabaseDirectory/QueryParams.h"
#include "ServiceBroker.h"
#include "filesystem/File.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp
index 00e1bce6f3..cb143c1ecc 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp
@@ -25,6 +25,7 @@
#include "DirectoryNodeSongTop100.h"
#include "DirectoryNodeTop100.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "URL.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp
index f274b59341..013c30bd65 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeAlbumRecentlyAdded.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp
index 77940c27f1..8080d5e7e0 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeAlbumRecentlyPlayed.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp
index 88ffaff77a..753b756ac8 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeAlbumTop100.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp
index fefeb6d666..cca955e4b7 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp
index fff9228b58..36bacfeb55 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTop100.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicFileDirectory.cpp b/xbmc/filesystem/MusicFileDirectory.cpp
index b3c7749c47..51340b54eb 100644
--- a/xbmc/filesystem/MusicFileDirectory.cpp
+++ b/xbmc/filesystem/MusicFileDirectory.cpp
@@ -9,6 +9,7 @@
#include "MusicFileDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicSearchDirectory.cpp b/xbmc/filesystem/MusicSearchDirectory.cpp
index 1d1868ab1a..2f8c8200cc 100644
--- a/xbmc/filesystem/MusicSearchDirectory.cpp
+++ b/xbmc/filesystem/MusicSearchDirectory.cpp
@@ -9,6 +9,7 @@
#include "MusicSearchDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
diff --git a/xbmc/filesystem/NFSDirectory.cpp b/xbmc/filesystem/NFSDirectory.cpp
index 7feba534c7..6d3588dccc 100644
--- a/xbmc/filesystem/NFSDirectory.cpp
+++ b/xbmc/filesystem/NFSDirectory.cpp
@@ -13,6 +13,7 @@
#endif
#include "FileItem.h"
+#include "FileItemList.h"
#include "NFSDirectory.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/PlaylistDirectory.cpp b/xbmc/filesystem/PlaylistDirectory.cpp
index 8be88dc581..f656c77dab 100644
--- a/xbmc/filesystem/PlaylistDirectory.cpp
+++ b/xbmc/filesystem/PlaylistDirectory.cpp
@@ -9,6 +9,7 @@
#include "PlaylistDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/filesystem/PlaylistFileDirectory.cpp b/xbmc/filesystem/PlaylistFileDirectory.cpp
index 2bdb243680..108c9c9a65 100644
--- a/xbmc/filesystem/PlaylistFileDirectory.cpp
+++ b/xbmc/filesystem/PlaylistFileDirectory.cpp
@@ -9,6 +9,7 @@
#include "PlaylistFileDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/File.h"
#include "playlists/PlayList.h"
diff --git a/xbmc/filesystem/PluginDirectory.cpp b/xbmc/filesystem/PluginDirectory.cpp
index cf3ded1286..4269fa4236 100644
--- a/xbmc/filesystem/PluginDirectory.cpp
+++ b/xbmc/filesystem/PluginDirectory.cpp
@@ -9,6 +9,7 @@
#include "PluginDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "addons/AddonInstaller.h"
diff --git a/xbmc/filesystem/RSSDirectory.cpp b/xbmc/filesystem/RSSDirectory.cpp
index 65bc876c6c..ac0a704221 100644
--- a/xbmc/filesystem/RSSDirectory.cpp
+++ b/xbmc/filesystem/RSSDirectory.cpp
@@ -10,6 +10,7 @@
#include "CurlFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "settings/AdvancedSettings.h"
diff --git a/xbmc/filesystem/ResourceDirectory.cpp b/xbmc/filesystem/ResourceDirectory.cpp
index c3623d0ce0..6526fb56be 100644
--- a/xbmc/filesystem/ResourceDirectory.cpp
+++ b/xbmc/filesystem/ResourceDirectory.cpp
@@ -9,6 +9,7 @@
#include "ResourceDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/Directory.h"
#include "filesystem/ResourceFile.h"
diff --git a/xbmc/filesystem/SmartPlaylistDirectory.cpp b/xbmc/filesystem/SmartPlaylistDirectory.cpp
index a45e796071..b3d361ecc2 100644
--- a/xbmc/filesystem/SmartPlaylistDirectory.cpp
+++ b/xbmc/filesystem/SmartPlaylistDirectory.cpp
@@ -9,6 +9,7 @@
#include "SmartPlaylistDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "filesystem/File.h"
diff --git a/xbmc/filesystem/SourcesDirectory.cpp b/xbmc/filesystem/SourcesDirectory.cpp
index a7af4cf118..0f36fbb88e 100644
--- a/xbmc/filesystem/SourcesDirectory.cpp
+++ b/xbmc/filesystem/SourcesDirectory.cpp
@@ -9,6 +9,7 @@
#include "SourcesDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/filesystem/SpecialProtocolDirectory.cpp b/xbmc/filesystem/SpecialProtocolDirectory.cpp
index e4a970ea99..d1af8b0345 100644
--- a/xbmc/filesystem/SpecialProtocolDirectory.cpp
+++ b/xbmc/filesystem/SpecialProtocolDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "SpecialProtocol.h"
#include "URL.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/StackDirectory.cpp b/xbmc/filesystem/StackDirectory.cpp
index 58cbe9dff9..9b6aae53b0 100644
--- a/xbmc/filesystem/StackDirectory.cpp
+++ b/xbmc/filesystem/StackDirectory.cpp
@@ -9,6 +9,7 @@
#include "StackDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "settings/AdvancedSettings.h"
diff --git a/xbmc/filesystem/UDFDirectory.cpp b/xbmc/filesystem/UDFDirectory.cpp
index 236b281303..b22b496d1d 100644
--- a/xbmc/filesystem/UDFDirectory.cpp
+++ b/xbmc/filesystem/UDFDirectory.cpp
@@ -12,6 +12,7 @@
#include "UDFDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "Util.h"
#include "filesystem/UDFBlockInput.h"
diff --git a/xbmc/filesystem/UPnPDirectory.cpp b/xbmc/filesystem/UPnPDirectory.cpp
index 4d6608acfa..2b2af57598 100644
--- a/xbmc/filesystem/UPnPDirectory.cpp
+++ b/xbmc/filesystem/UPnPDirectory.cpp
@@ -13,6 +13,7 @@
#include "UPnPDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "network/upnp/UPnP.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory.cpp b/xbmc/filesystem/VideoDatabaseDirectory.cpp
index 2c9caa7080..4242b095ce 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory.cpp
@@ -10,6 +10,7 @@
#include "File.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "VideoDatabaseDirectory/QueryParams.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp
index b62839c9bc..f181b4514a 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp
@@ -24,6 +24,7 @@
#include "DirectoryNodeTitleTvShows.h"
#include "DirectoryNodeTvShowsOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "URL.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp
index 9f629baa69..c75471cb0f 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeEpisodes.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp
index 044f8b3c74..f0a652232e 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeInProgressTvShows.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp
index 9f415d09da..33d70051d8 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeMoviesOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp
index b71d8f1d2b..9c7290abc5 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeMusicVideosOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "video/VideoDbUrl.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp
index b52ae24dc5..0aeed45edc 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
#include "settings/Settings.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp
index fe50dad926..317c761002 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeRecentlyAddedEpisodes.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp
index 202d6f7b4a..41b372beb6 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeRecentlyAddedMovies.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp
index d8ba5ef74d..2f57643b43 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeRecentlyAddedMusicVideos.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp
index 45a83cee8f..0e82fcca9e 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTitleMovies.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp
index 95fe30010b..d35398b153 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTitleMusicVideos.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp
index b1a247ca7f..52f903fffd 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTitleTvShows.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp
index 07e5ff4aee..5a490a53d7 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTvShowsOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "video/VideoDbUrl.h"
diff --git a/xbmc/filesystem/VirtualDirectory.cpp b/xbmc/filesystem/VirtualDirectory.cpp
index 4fb0205d1e..f764645cf9 100644
--- a/xbmc/filesystem/VirtualDirectory.cpp
+++ b/xbmc/filesystem/VirtualDirectory.cpp
@@ -11,6 +11,7 @@
#include "Directory.h"
#include "DirectoryFactory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "SourcesDirectory.h"
#include "URL.h"
diff --git a/xbmc/filesystem/ZeroconfDirectory.cpp b/xbmc/filesystem/ZeroconfDirectory.cpp
index f34b6b2f1f..d05184e394 100644
--- a/xbmc/filesystem/ZeroconfDirectory.cpp
+++ b/xbmc/filesystem/ZeroconfDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "network/ZeroconfBrowser.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/test/TestDirectory.cpp b/xbmc/filesystem/test/TestDirectory.cpp
index e99408c9dc..8f65b06356 100644
--- a/xbmc/filesystem/test/TestDirectory.cpp
+++ b/xbmc/filesystem/test/TestDirectory.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "filesystem/IDirectory.h"
#include "filesystem/SpecialProtocol.h"
diff --git a/xbmc/filesystem/test/TestHTTPDirectory.cpp b/xbmc/filesystem/test/TestHTTPDirectory.cpp
index 773630770b..8288bda46f 100644
--- a/xbmc/filesystem/test/TestHTTPDirectory.cpp
+++ b/xbmc/filesystem/test/TestHTTPDirectory.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/CurlFile.h"
#include "filesystem/HTTPDirectory.h"
diff --git a/xbmc/filesystem/test/TestZipFile.cpp b/xbmc/filesystem/test/TestZipFile.cpp
index 3ff518b8dc..ffb4478cdd 100644
--- a/xbmc/filesystem/test/TestZipFile.cpp
+++ b/xbmc/filesystem/test/TestZipFile.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/games/addons/GameClientProperties.cpp b/xbmc/games/addons/GameClientProperties.cpp
index f3d97858bd..ae081afa92 100644
--- a/xbmc/games/addons/GameClientProperties.cpp
+++ b/xbmc/games/addons/GameClientProperties.cpp
@@ -9,6 +9,7 @@
#include "GameClientProperties.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GameClient.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/games/agents/windows/GUIAgentControllerList.cpp b/xbmc/games/agents/windows/GUIAgentControllerList.cpp
index 55bb3e2296..7da49e72d2 100644
--- a/xbmc/games/agents/windows/GUIAgentControllerList.cpp
+++ b/xbmc/games/agents/windows/GUIAgentControllerList.cpp
@@ -9,6 +9,7 @@
#include "GUIAgentControllerList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIAgentDefines.h"
#include "GUIAgentWindow.h"
#include "ServiceBroker.h"
diff --git a/xbmc/games/controllers/dialogs/ControllerInstaller.cpp b/xbmc/games/controllers/dialogs/ControllerInstaller.cpp
index 9b0fe6fc87..18f7634a01 100644
--- a/xbmc/games/controllers/dialogs/ControllerInstaller.cpp
+++ b/xbmc/games/controllers/dialogs/ControllerInstaller.cpp
@@ -9,6 +9,7 @@
#include "ControllerInstaller.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/Addon.h"
#include "addons/AddonInstaller.h"
diff --git a/xbmc/games/controllers/dialogs/ControllerSelect.cpp b/xbmc/games/controllers/dialogs/ControllerSelect.cpp
index 2ef9941dea..8219731120 100644
--- a/xbmc/games/controllers/dialogs/ControllerSelect.cpp
+++ b/xbmc/games/controllers/dialogs/ControllerSelect.cpp
@@ -9,6 +9,7 @@
#include "ControllerSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogSelect.h"
#include "games/controllers/Controller.h"
diff --git a/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp b/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
index f4c754aee0..08d6b71ffb 100644
--- a/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
+++ b/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSelectGameClient.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "dialogs/GUIDialogSelect.h"
#include "filesystem/AddonsDirectory.h"
#include "games/addons/GameClient.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameSaves.cpp b/xbmc/games/dialogs/osd/DialogGameSaves.cpp
index a2c08d606f..239b78ab4e 100644
--- a/xbmc/games/dialogs/osd/DialogGameSaves.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameSaves.cpp
@@ -9,6 +9,7 @@
#include "DialogGameSaves.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/Addon.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp b/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp
index 98c1e077e8..67f4cad1ff 100644
--- a/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp
@@ -9,6 +9,7 @@
#include "DialogGameStretchMode.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "cores/RetroPlayer/RetroPlayerUtils.h"
#include "cores/RetroPlayer/guibridge/GUIGameVideoHandle.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameVideoFilter.h b/xbmc/games/dialogs/osd/DialogGameVideoFilter.h
index 237720d65d..6c659da6e0 100644
--- a/xbmc/games/dialogs/osd/DialogGameVideoFilter.h
+++ b/xbmc/games/dialogs/osd/DialogGameVideoFilter.h
@@ -10,6 +10,7 @@
#include "DialogGameVideoSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
namespace KODI
{
diff --git a/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp b/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp
index 7037a6b35c..3fe6baa778 100644
--- a/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp
@@ -9,6 +9,7 @@
#include "DialogGameVideoRotation.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "guilib/WindowIDs.h"
#include "settings/GameSettings.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp b/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp
index a69b26f772..0bf1529244 100644
--- a/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp
@@ -9,6 +9,7 @@
#include "DialogGameVideoSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "cores/RetroPlayer/guibridge/GUIGameRenderManager.h"
#include "cores/RetroPlayer/guibridge/GUIGameVideoHandle.h"
diff --git a/xbmc/games/dialogs/osd/DialogInGameSaves.h b/xbmc/games/dialogs/osd/DialogInGameSaves.h
index 5c1c3176c7..8fdb7b0b6c 100644
--- a/xbmc/games/dialogs/osd/DialogInGameSaves.h
+++ b/xbmc/games/dialogs/osd/DialogInGameSaves.h
@@ -10,6 +10,7 @@
#include "DialogGameVideoSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/GUIListItem.h"
#include <string>
diff --git a/xbmc/games/ports/guicontrols/GUIActivePortList.cpp b/xbmc/games/ports/guicontrols/GUIActivePortList.cpp
index 851ca86266..f0e89f6e8d 100644
--- a/xbmc/games/ports/guicontrols/GUIActivePortList.cpp
+++ b/xbmc/games/ports/guicontrols/GUIActivePortList.cpp
@@ -9,6 +9,7 @@
#include "GUIActivePortList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/AddonEvents.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/games/ports/windows/GUIPortList.cpp b/xbmc/games/ports/windows/GUIPortList.cpp
index c0e46e0bac..9db78747be 100644
--- a/xbmc/games/ports/windows/GUIPortList.cpp
+++ b/xbmc/games/ports/windows/GUIPortList.cpp
@@ -9,6 +9,7 @@
#include "GUIPortList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPortDefines.h"
#include "GUIPortWindow.h"
#include "ServiceBroker.h"
diff --git a/xbmc/games/windows/GUIViewStateWindowGames.cpp b/xbmc/games/windows/GUIViewStateWindowGames.cpp
index e388d8ff83..3f45122ac7 100644
--- a/xbmc/games/windows/GUIViewStateWindowGames.cpp
+++ b/xbmc/games/windows/GUIViewStateWindowGames.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateWindowGames.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "games/GameUtils.h"
#include "guilib/LocalizeStrings.h"
#include "guilib/WindowIDs.h"
diff --git a/xbmc/games/windows/GUIWindowGames.cpp b/xbmc/games/windows/GUIWindowGames.cpp
index a74186db84..2d9eb600db 100644
--- a/xbmc/games/windows/GUIWindowGames.cpp
+++ b/xbmc/games/windows/GUIWindowGames.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowGames.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/guilib/GUIBaseContainer.cpp b/xbmc/guilib/GUIBaseContainer.cpp
index 897459790d..65d604c18f 100644
--- a/xbmc/guilib/GUIBaseContainer.cpp
+++ b/xbmc/guilib/GUIBaseContainer.cpp
@@ -9,6 +9,7 @@
#include "GUIBaseContainer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIListItemLayout.h"
#include "GUIMessage.h"
diff --git a/xbmc/guilib/GUIFontManager.cpp b/xbmc/guilib/GUIFontManager.cpp
index 9170cc0406..93f88666a0 100644
--- a/xbmc/guilib/GUIFontManager.cpp
+++ b/xbmc/guilib/GUIFontManager.cpp
@@ -8,6 +8,7 @@
#include "GUIFontManager.h"
+#include "FileItemList.h"
#include "GUIComponent.h"
#include "GUIFontTTF.h"
#include "GUIWindowManager.h"
diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
index d19c1f0a3f..ff11db14f8 100644
--- a/xbmc/guilib/GUIFontTTF.cpp
+++ b/xbmc/guilib/GUIFontTTF.cpp
@@ -382,7 +382,7 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
uint32_t rawAlignment = alignment;
bool dirtyCache(false);
-#if defined(HAS_GL)
+#if not defined(HAS_DX)
// round coordinates to the pixel grid. otherwise, we might sample at the wrong positions.
if (!scrolling)
x = std::round(x);
@@ -392,7 +392,7 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
y += dy;
#endif
-#if defined(HAS_GL)
+#if not defined(HAS_DX)
// GL can scissor and shader clip
const bool hardwareClipping = true;
#else
@@ -404,7 +404,7 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
CGUIFontCacheStaticPosition staticPos(x, y);
CGUIFontCacheDynamicPosition dynamicPos;
-#if defined(HAS_GL)
+#if not defined(HAS_DX)
// dummy positions for the time being
dynamicPos = CGUIFontCacheDynamicPosition(0.0f, 0.0f, 0.0f);
#else
@@ -452,7 +452,7 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
const std::vector<Glyph> glyphs = GetHarfBuzzShapedGlyphs(text);
// save the origin, which is scaled separately
-#if defined(HAS_GL)
+#if not defined(HAS_DX)
// the origin is now at [0,0], and not at "random" locations anymore. positioning is done in the vertex shader.
m_originX = 0;
m_originY = 0;
@@ -710,7 +710,7 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
scrolling, std::chrono::steady_clock::now(), dirtyCache);
CVertexBuffer newVertexBuffer = CreateVertexBuffer(*tempVertices);
vertexBuffer = newVertexBuffer;
-#if defined(HAS_GL)
+#if not defined(HAS_DX)
m_vertexTrans.emplace_back(x, y, 0.0f, &vertexBuffer, context.GetClipRegion(), dx, dy);
#else
m_vertexTrans.emplace_back(.0f, .0f, .0f, &vertexBuffer, context.GetClipRegion());
@@ -728,7 +728,7 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
else
{
if (hardwareClipping)
-#if defined(HAS_GL)
+#if not defined(HAS_DX)
m_vertexTrans.emplace_back(x, y, 0.0f, &vertexBuffer, context.GetClipRegion(), dx, dy);
#else
m_vertexTrans.emplace_back(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer,
@@ -1139,7 +1139,7 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
// posX and posY are relative to our origin, and the textcell is offset
// from our (posX, posY). Plus, these are unscaled quantities compared to the underlying GUI resolution
-#if defined(HAS_GL)
+#if not defined(HAS_DX)
CRect vertex((posX + ch->m_offsetX), (posY + ch->m_offsetY), (posX + ch->m_offsetX + width),
(posY + ch->m_offsetY + height));
#else
@@ -1151,7 +1151,7 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
#endif
CRect texture(ch->m_left, ch->m_top, ch->m_right, ch->m_bottom);
-#if !defined(HAS_GL)
+#if defined(HAS_DX)
if (!m_renderSystem->ScissorsCanEffectClipping())
context.ClipRect(vertex, texture);
@@ -1262,7 +1262,7 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
v[3].u = tl;
v[3].v = tb;
-#elif defined(HAS_GL)
+#else
// GL / GLES uses triangle strips, not quads, so have to rearrange the vertex order
// GL uses vertex shaders to manipulate text rotation/translation/scaling/clipping.
@@ -1296,30 +1296,6 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
v[3].x = vertex.x2 - xOffset + 0.5f;
v[3].y = vertex.y2 - yOffset + 0.5f;
v[3].z = 0;
-#else
- v[0].u = tl;
- v[0].v = tt;
- v[0].x = x[0];
- v[0].y = y[0];
- v[0].z = z[0];
-
- v[1].u = tl;
- v[1].v = tb;
- v[1].x = x[3];
- v[1].y = y[3];
- v[1].z = z[3];
-
- v[2].u = tr;
- v[2].v = tt;
- v[2].x = x[1];
- v[2].y = y[1];
- v[2].z = z[1];
-
- v[3].u = tr;
- v[3].v = tb;
- v[3].x = x[2];
- v[3].y = y[2];
- v[3].z = z[2];
#endif
}
diff --git a/xbmc/guilib/GUIFontTTFGLES.cpp b/xbmc/guilib/GUIFontTTFGLES.cpp
index c00a601319..67cceae441 100644
--- a/xbmc/guilib/GUIFontTTFGLES.cpp
+++ b/xbmc/guilib/GUIFontTTFGLES.cpp
@@ -62,6 +62,17 @@ bool CGUIFontTTFGLES::FirstBegin()
GLenum pixformat = GL_ALPHA; // deprecated
GLenum internalFormat = GL_ALPHA;
+ if (renderSystem->ScissorsCanEffectClipping())
+ {
+ m_scissorClip = true;
+ }
+ else
+ {
+ m_scissorClip = false;
+ renderSystem->ResetScissors();
+ renderSystem->EnableGUIShader(ShaderMethodGLES::SM_FONTS_SHADER_CLIP);
+ }
+
if (m_textureStatus == TEXTURE_REALLOCATED)
{
if (glIsTexture(m_nTexture))
@@ -124,6 +135,9 @@ bool CGUIFontTTFGLES::FirstBegin()
void CGUIFontTTFGLES::LastEnd()
{
+ // static vertex arrays are not supported anymore
+ assert(m_vertex.empty());
+
CWinSystemBase* const winSystem = CServiceBroker::GetWinSystem();
if (!winSystem)
return;
@@ -134,7 +148,9 @@ void CGUIFontTTFGLES::LastEnd()
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint colLoc = renderSystem->GUIShaderGetCol();
GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
- GLint modelLoc = renderSystem->GUIShaderGetModel();
+ GLint clipUniformLoc = renderSystem->GUIShaderGetClip();
+ GLint coordStepUniformLoc = renderSystem->GUIShaderGetCoordStep();
+ GLint matrixUniformLoc = renderSystem->GUIShaderGetMatrix();
CreateStaticVertexBuffers();
@@ -143,35 +159,6 @@ void CGUIFontTTFGLES::LastEnd()
glEnableVertexAttribArray(colLoc);
glEnableVertexAttribArray(tex0Loc);
- if (!m_vertex.empty())
- {
- // Deal with vertices that had to use software clipping
- std::vector<SVertex> vecVertices(6 * (m_vertex.size() / 4));
- SVertex* vertices = &vecVertices[0];
-
- for (size_t i = 0; i < m_vertex.size(); i += 4)
- {
- *vertices++ = m_vertex[i];
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 2];
-
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 3];
- *vertices++ = m_vertex[i + 2];
- }
-
- vertices = &vecVertices[0];
-
- glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<char*>(vertices) + offsetof(SVertex, x));
- glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex),
- reinterpret_cast<char*>(vertices) + offsetof(SVertex, r));
- glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<char*>(vertices) + offsetof(SVertex, u));
-
- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
- }
-
if (!m_vertexTrans.empty())
{
// Deal with the vertices that can be hardware clipped and therefore translated
@@ -198,14 +185,54 @@ void CGUIFontTTFGLES::LastEnd()
// skip empty clip
if (clip.IsEmpty())
continue;
+ }
+ if (m_scissorClip)
+ {
+ // clip using scissors
renderSystem->SetScissors(clip);
}
+ else
+ {
+ // clip using vertex shader
+ renderSystem->ResetScissors();
+
+ float x1 =
+ m_vertexTrans[i].m_clip.x1 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y1 =
+ m_vertexTrans[i].m_clip.y1 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+ float x2 =
+ m_vertexTrans[i].m_clip.x2 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y2 =
+ m_vertexTrans[i].m_clip.y2 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+
+ glUniform4f(clipUniformLoc, x1, y1, x2, y2);
+
+ // setup texture step
+ float stepX = context.GetGUIScaleX() / (static_cast<float>(m_textureWidth));
+ float stepY = context.GetGUIScaleY() / (static_cast<float>(m_textureHeight));
+ glUniform4f(coordStepUniformLoc, stepX, stepY, 1.0f, 1.0f);
+ }
- // Apply the translation to the currently active (top-of-stack) model view matrix
- glMatrixModview.Push();
- glMatrixModview.Get().Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY,
- m_vertexTrans[i].m_translateZ);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ // calculate the fractional offset to the ideal position
+ float fractX =
+ context.ScaleFinalXCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ float fractY =
+ context.ScaleFinalYCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ fractX = -fractX + std::round(fractX);
+ fractY = -fractY + std::round(fractY);
+
+ // proj * model * gui * scroll * translation * scaling * correction factor
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ matrix.MultMatrixf(CMatrixGL(context.GetGUIMatrix()));
+ matrix.Translatef(m_vertexTrans[i].m_offsetX, m_vertexTrans[i].m_offsetY, 0.0f);
+ matrix.Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY, 0.0f);
+ // the gui matrix messes with the scale. correct it here for now.
+ matrix.Scalef(context.GetGUIScaleX(), context.GetGUIScaleY(), 1.0f);
+ // the gui matrix doesn't align to exact pixel coords atm. correct it here for now.
+ matrix.Translatef(fractX, fractY, 0.0f);
+
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
// Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point
glBindBuffer(GL_ARRAY_BUFFER, m_vertexTrans[i].m_vertexBuffer->bufferHandle);
@@ -236,9 +263,8 @@ void CGUIFontTTFGLES::LastEnd()
glMatrixModview.Pop();
}
// Restore the original scissor rectangle
- renderSystem->SetScissors(scissor);
- // Restore the original model view matrix
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ if (m_scissorClip)
+ renderSystem->SetScissors(scissor);
// Unbind GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
diff --git a/xbmc/guilib/GUIFontTTFGLES.h b/xbmc/guilib/GUIFontTTFGLES.h
index ae03da74e6..264d1a7611 100644
--- a/xbmc/guilib/GUIFontTTFGLES.h
+++ b/xbmc/guilib/GUIFontTTFGLES.h
@@ -55,4 +55,5 @@ private:
TextureStatus m_textureStatus{TEXTURE_VOID};
static bool m_staticVertexBufferCreated;
+ bool m_scissorClip{false};
};
diff --git a/xbmc/guilib/GUIMultiImage.cpp b/xbmc/guilib/GUIMultiImage.cpp
index e42dc8b1b3..efc5c18b4b 100644
--- a/xbmc/guilib/GUIMultiImage.cpp
+++ b/xbmc/guilib/GUIMultiImage.cpp
@@ -9,6 +9,7 @@
#include "GUIMultiImage.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIMessage.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
diff --git a/xbmc/guilib/guiinfo/GUIInfoLabels.h b/xbmc/guilib/guiinfo/GUIInfoLabels.h
index 68faf15e98..88897afcd8 100644
--- a/xbmc/guilib/guiinfo/GUIInfoLabels.h
+++ b/xbmc/guilib/guiinfo/GUIInfoLabels.h
@@ -483,7 +483,8 @@
#define SYSTEM_MEDIA_AUDIO_CD 754
#define SYSTEM_PLATFORM_DARWIN_TVOS 755
-#define SYSTEM_SUPPORTED_HDR_TYPES 756
+#define SYSTEM_SUPPORTED_HDR_TYPES 756
+#define SYSTEM_PLATFORM_WEBOS 757
#define SLIDESHOW_ISPAUSED 800
#define SLIDESHOW_ISRANDOM 801
diff --git a/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp b/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp
index f7aceadb7f..0ffcafee4b 100644
--- a/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp
@@ -9,6 +9,7 @@
#include "guilib/guiinfo/LibraryGUIInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/guilib/guiinfo/SystemGUIInfo.cpp b/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
index 70794125c4..da1d7dc97b 100644
--- a/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
@@ -9,6 +9,7 @@
#include "guilib/guiinfo/SystemGUIInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
@@ -451,6 +452,13 @@ bool CSystemGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int context
value = false;
#endif
return true;
+ case SYSTEM_PLATFORM_WEBOS:
+#if defined(TARGET_WEBOS)
+ value = true;
+#else
+ value = false;
+#endif
+ return true;
case SYSTEM_MEDIA_DVD:
value = CServiceBroker::GetMediaManager().IsDiscInDrive();
return true;
diff --git a/xbmc/input/keyboard/KeyboardLayoutManager.cpp b/xbmc/input/keyboard/KeyboardLayoutManager.cpp
index 4727a633ed..98ba2c5020 100644
--- a/xbmc/input/keyboard/KeyboardLayoutManager.cpp
+++ b/xbmc/input/keyboard/KeyboardLayoutManager.cpp
@@ -9,6 +9,7 @@
#include "KeyboardLayoutManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/input/keymaps/ButtonTranslator.cpp b/xbmc/input/keymaps/ButtonTranslator.cpp
index a7d3e50e57..34aa0164bd 100644
--- a/xbmc/input/keymaps/ButtonTranslator.cpp
+++ b/xbmc/input/keymaps/ButtonTranslator.cpp
@@ -10,6 +10,7 @@
#include "AppTranslator.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "guilib/WindowIDs.h"
#include "input/WindowTranslator.h"
diff --git a/xbmc/interfaces/builtins/PlayerBuiltins.cpp b/xbmc/interfaces/builtins/PlayerBuiltins.cpp
index 10897723d9..2173959123 100644
--- a/xbmc/interfaces/builtins/PlayerBuiltins.cpp
+++ b/xbmc/interfaces/builtins/PlayerBuiltins.cpp
@@ -9,6 +9,7 @@
#include "PlayerBuiltins.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
diff --git a/xbmc/interfaces/json-rpc/AddonsOperations.cpp b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
index db6c90a191..3daac8cc0b 100644
--- a/xbmc/interfaces/json-rpc/AddonsOperations.cpp
+++ b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
@@ -11,7 +11,6 @@
#include "JSONUtils.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
-#include "addons/AddonDatabase.h"
#include "addons/AddonManager.h"
#include "addons/PluginSource.h"
#include "addons/addoninfo/AddonInfo.h"
@@ -122,9 +121,8 @@ JSONRPC_STATUS CAddonsOperations::GetAddons(const std::string &method, ITranspor
int start, end;
HandleLimits(parameterObject, result, addons.size(), start, end);
- CAddonDatabase addondb;
for (int index = start; index < end; index++)
- FillDetails(addons.at(index), parameterObject["properties"], result["addons"], addondb, true);
+ FillDetails(addons.at(index), parameterObject["properties"], result["addons"], true);
return OK;
}
@@ -138,8 +136,7 @@ JSONRPC_STATUS CAddonsOperations::GetAddonDetails(const std::string &method, ITr
addon->Type() >= AddonType::MAX_TYPES)
return InvalidParams;
- CAddonDatabase addondb;
- FillDetails(addon, parameterObject["properties"], result["addon"], addondb);
+ FillDetails(addon, parameterObject["properties"], result["addon"], false);
return OK;
}
@@ -272,8 +269,7 @@ static CVariant Serialize(const AddonPtr& addon)
void CAddonsOperations::FillDetails(const std::shared_ptr<ADDON::IAddon>& addon,
const CVariant& fields,
CVariant& result,
- CAddonDatabase& addondb,
- bool append /* = false */)
+ bool append)
{
if (addon.get() == NULL)
return;
diff --git a/xbmc/interfaces/json-rpc/AddonsOperations.h b/xbmc/interfaces/json-rpc/AddonsOperations.h
index 727f418999..cf78a2dba0 100644
--- a/xbmc/interfaces/json-rpc/AddonsOperations.h
+++ b/xbmc/interfaces/json-rpc/AddonsOperations.h
@@ -35,7 +35,6 @@ namespace JSONRPC
static void FillDetails(const std::shared_ptr<ADDON::IAddon>& addon,
const CVariant& fields,
CVariant& result,
- ADDON::CAddonDatabase& addondb,
- bool append = false);
+ bool append);
};
}
diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.cpp b/xbmc/interfaces/json-rpc/AudioLibrary.cpp
index 3d6fa79d79..951cd7ae8d 100644
--- a/xbmc/interfaces/json-rpc/AudioLibrary.cpp
+++ b/xbmc/interfaces/json-rpc/AudioLibrary.cpp
@@ -9,6 +9,7 @@
#include "AudioLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
#include "Util.h"
diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
index 07426447e1..7a524fd337 100644
--- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp
+++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -9,6 +9,7 @@
#include "FileItemHandler.h"
#include "AudioLibrary.h"
+#include "FileItemList.h"
#include "FileOperations.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
diff --git a/xbmc/interfaces/json-rpc/FileOperations.cpp b/xbmc/interfaces/json-rpc/FileOperations.cpp
index 4658e99353..a495607ff9 100644
--- a/xbmc/interfaces/json-rpc/FileOperations.cpp
+++ b/xbmc/interfaces/json-rpc/FileOperations.cpp
@@ -10,6 +10,7 @@
#include "AudioLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MediaSource.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp
index 0ec809481c..07c8d93222 100644
--- a/xbmc/interfaces/json-rpc/PVROperations.cpp
+++ b/xbmc/interfaces/json-rpc/PVROperations.cpp
@@ -9,6 +9,7 @@
#include "PVROperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/PVRPlaybackState.h"
diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
index 5029549541..02747f18fb 100644
--- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp
+++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
@@ -10,6 +10,7 @@
#include "AudioLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
diff --git a/xbmc/interfaces/json-rpc/PlaylistOperations.cpp b/xbmc/interfaces/json-rpc/PlaylistOperations.cpp
index 61e04ac711..49955bc68f 100644
--- a/xbmc/interfaces/json-rpc/PlaylistOperations.cpp
+++ b/xbmc/interfaces/json-rpc/PlaylistOperations.cpp
@@ -9,6 +9,7 @@
#include "PlaylistOperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
diff --git a/xbmc/interfaces/json-rpc/ProfilesOperations.cpp b/xbmc/interfaces/json-rpc/ProfilesOperations.cpp
index adfb010430..17facb7b0e 100644
--- a/xbmc/interfaces/json-rpc/ProfilesOperations.cpp
+++ b/xbmc/interfaces/json-rpc/ProfilesOperations.cpp
@@ -9,6 +9,7 @@
#include "ProfilesOperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/interfaces/json-rpc/TextureOperations.cpp b/xbmc/interfaces/json-rpc/TextureOperations.cpp
index d6ffcc8761..d6915314bf 100644
--- a/xbmc/interfaces/json-rpc/TextureOperations.cpp
+++ b/xbmc/interfaces/json-rpc/TextureOperations.cpp
@@ -9,6 +9,7 @@
#include "TextureOperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "TextureDatabase.h"
diff --git a/xbmc/interfaces/json-rpc/VideoLibrary.cpp b/xbmc/interfaces/json-rpc/VideoLibrary.cpp
index 0f7499ec0e..cb69a5f002 100644
--- a/xbmc/interfaces/json-rpc/VideoLibrary.cpp
+++ b/xbmc/interfaces/json-rpc/VideoLibrary.cpp
@@ -9,6 +9,7 @@
#include "VideoLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PVROperations.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
diff --git a/xbmc/interfaces/legacy/Control.cpp b/xbmc/interfaces/legacy/Control.cpp
index 2ad9c2197e..d75778b5f5 100644
--- a/xbmc/interfaces/legacy/Control.cpp
+++ b/xbmc/interfaces/legacy/Control.cpp
@@ -9,6 +9,7 @@
#include "Control.h"
#include "AddonUtils.h"
+#include "FileItemList.h"
#include "LanguageHook.h"
#include "ServiceBroker.h"
#include "WindowException.h"
diff --git a/xbmc/interfaces/legacy/Dialog.cpp b/xbmc/interfaces/legacy/Dialog.cpp
index 55812f9099..9674875ea1 100644
--- a/xbmc/interfaces/legacy/Dialog.cpp
+++ b/xbmc/interfaces/legacy/Dialog.cpp
@@ -7,6 +7,7 @@
*/
#include "Dialog.h"
+#include "FileItemList.h"
#include "LanguageHook.h"
#include "ListItem.h"
#include "ModuleXbmcgui.h"
diff --git a/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp b/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp
index 0af97b71ac..bc399cc1c9 100644
--- a/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp
+++ b/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp
@@ -9,6 +9,7 @@
#include "ModuleXbmcplugin.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/PluginDirectory.h"
namespace XBMCAddon
diff --git a/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp b/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp
index c6858e3617..0d2391523f 100644
--- a/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp
+++ b/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp
@@ -9,6 +9,7 @@
#include "ModuleXbmcvfs.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LanguageHook.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/interfaces/legacy/PlayList.cpp b/xbmc/interfaces/legacy/PlayList.cpp
index d6d19d8866..649bc89892 100644
--- a/xbmc/interfaces/legacy/PlayList.cpp
+++ b/xbmc/interfaces/legacy/PlayList.cpp
@@ -8,6 +8,7 @@
#include "PlayList.h"
+#include "FileItemList.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
#include "playlists/PlayListFactory.h"
diff --git a/xbmc/interfaces/legacy/Player.cpp b/xbmc/interfaces/legacy/Player.cpp
index 4fc961cd88..b3aff2dfd5 100644
--- a/xbmc/interfaces/legacy/Player.cpp
+++ b/xbmc/interfaces/legacy/Player.cpp
@@ -9,6 +9,7 @@
#include "Player.h"
#include "AddonUtils.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "ListItem.h"
diff --git a/xbmc/interfaces/legacy/WindowXML.cpp b/xbmc/interfaces/legacy/WindowXML.cpp
index 65dc6c47f9..b127496783 100644
--- a/xbmc/interfaces/legacy/WindowXML.cpp
+++ b/xbmc/interfaces/legacy/WindowXML.cpp
@@ -8,6 +8,7 @@
#include "WindowXML.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "WindowException.h"
#include "WindowInterceptor.h"
diff --git a/xbmc/music/GUIViewStateMusic.cpp b/xbmc/music/GUIViewStateMusic.cpp
index d57ebd8b2f..a34d9170a2 100644
--- a/xbmc/music/GUIViewStateMusic.cpp
+++ b/xbmc/music/GUIViewStateMusic.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateMusic.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "filesystem/MusicDatabaseDirectory.h"
diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp
index b5ba07ef8a..a98db00388 100644
--- a/xbmc/music/MusicDatabase.cpp
+++ b/xbmc/music/MusicDatabase.cpp
@@ -11,6 +11,7 @@
#include "Album.h"
#include "Artist.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
diff --git a/xbmc/music/MusicInfoLoader.cpp b/xbmc/music/MusicInfoLoader.cpp
index 7cfa0352ff..3ecaa4a417 100644
--- a/xbmc/music/MusicInfoLoader.cpp
+++ b/xbmc/music/MusicInfoLoader.cpp
@@ -11,6 +11,7 @@
#include "Album.h"
#include "Artist.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MusicDatabase.h"
#include "MusicThumbLoader.h"
#include "ServiceBroker.h"
diff --git a/xbmc/music/MusicUtils.cpp b/xbmc/music/MusicUtils.cpp
index 2bc8785d8b..1984cbb2e8 100644
--- a/xbmc/music/MusicUtils.cpp
+++ b/xbmc/music/MusicUtils.cpp
@@ -9,6 +9,7 @@
#include "MusicUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
diff --git a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp
index d1559f77fd..fab40e850f 100644
--- a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp
+++ b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogMusicInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
diff --git a/xbmc/music/dialogs/GUIDialogSongInfo.h b/xbmc/music/dialogs/GUIDialogSongInfo.h
index 274f1acc0f..7aba18a52a 100644
--- a/xbmc/music/dialogs/GUIDialogSongInfo.h
+++ b/xbmc/music/dialogs/GUIDialogSongInfo.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/GUIDialog.h"
#include "threads/Event.h"
diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp
index f828b44914..3236470c78 100644
--- a/xbmc/music/infoscanner/MusicInfoScanner.cpp
+++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp
@@ -9,6 +9,7 @@
#include "MusicInfoScanner.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "MusicAlbumInfo.h"
diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp
index 1e4a863256..b6ced56366 100644
--- a/xbmc/music/windows/GUIWindowMusicBase.cpp
+++ b/xbmc/music/windows/GUIWindowMusicBase.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
diff --git a/xbmc/music/windows/GUIWindowMusicNav.cpp b/xbmc/music/windows/GUIWindowMusicNav.cpp
index 3e956294dc..086cbe607f 100644
--- a/xbmc/music/windows/GUIWindowMusicNav.cpp
+++ b/xbmc/music/windows/GUIWindowMusicNav.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowMusicNav.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
diff --git a/xbmc/music/windows/GUIWindowMusicPlaylist.cpp b/xbmc/music/windows/GUIWindowMusicPlaylist.cpp
index fe1d72a163..85252b86f9 100644
--- a/xbmc/music/windows/GUIWindowMusicPlaylist.cpp
+++ b/xbmc/music/windows/GUIWindowMusicPlaylist.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowMusicPlaylist.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
diff --git a/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp b/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp
index cf9e73e817..16ecdd0c3c 100644
--- a/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp
+++ b/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/music/windows/MusicFileItemListModifier.cpp b/xbmc/music/windows/MusicFileItemListModifier.cpp
index fe04aed423..5aef6139f2 100644
--- a/xbmc/music/windows/MusicFileItemListModifier.cpp
+++ b/xbmc/music/windows/MusicFileItemListModifier.cpp
@@ -9,6 +9,7 @@
#include "MusicFileItemListModifier.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/MusicDatabaseDirectory/DirectoryNode.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/network/AirPlayServer.cpp b/xbmc/network/AirPlayServer.cpp
index eaa0aa58fd..6b30e11e06 100644
--- a/xbmc/network/AirPlayServer.cpp
+++ b/xbmc/network/AirPlayServer.cpp
@@ -12,6 +12,7 @@
#include "AirPlayServer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "application/ApplicationComponents.h"
diff --git a/xbmc/network/upnp/UPnPRenderer.cpp b/xbmc/network/upnp/UPnPRenderer.cpp
index ff63888578..acc25a81a9 100644
--- a/xbmc/network/upnp/UPnPRenderer.cpp
+++ b/xbmc/network/upnp/UPnPRenderer.cpp
@@ -8,6 +8,7 @@
#include "UPnPRenderer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp
index b07eb0a950..17e9cbebc9 100644
--- a/xbmc/network/upnp/UPnPServer.cpp
+++ b/xbmc/network/upnp/UPnPServer.cpp
@@ -7,6 +7,7 @@
*/
#include "UPnPServer.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
diff --git a/xbmc/peripherals/addons/PeripheralAddon.cpp b/xbmc/peripherals/addons/PeripheralAddon.cpp
index d55dfb55ce..2b7aca7584 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddon.cpp
@@ -9,6 +9,7 @@
#include "PeripheralAddon.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PeripheralAddonTranslator.h"
#include "addons/addoninfo/AddonInfo.h"
#include "addons/addoninfo/AddonType.h"
diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp
index b59ba1dca3..f33b80181b 100644
--- a/xbmc/peripherals/bus/PeripheralBus.cpp
+++ b/xbmc/peripherals/bus/PeripheralBus.cpp
@@ -9,6 +9,7 @@
#include "PeripheralBus.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "peripherals/Peripherals.h"
#include "peripherals/devices/Peripheral.h"
diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripherals.h b/xbmc/peripherals/dialogs/GUIDialogPeripherals.h
index 8a54e01aca..4eedb2e390 100644
--- a/xbmc/peripherals/dialogs/GUIDialogPeripherals.h
+++ b/xbmc/peripherals/dialogs/GUIDialogPeripherals.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "dialogs/GUIDialogSelect.h"
#include "threads/CriticalSection.h"
#include "utils/Observer.h"
diff --git a/xbmc/pictures/GUIDialogPictureInfo.cpp b/xbmc/pictures/GUIDialogPictureInfo.cpp
index 263b48238f..2a4b8cc665 100644
--- a/xbmc/pictures/GUIDialogPictureInfo.cpp
+++ b/xbmc/pictures/GUIDialogPictureInfo.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPictureInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/pictures/GUIViewStatePictures.cpp b/xbmc/pictures/GUIViewStatePictures.cpp
index 47d0cdff7a..5b9ebfd208 100644
--- a/xbmc/pictures/GUIViewStatePictures.cpp
+++ b/xbmc/pictures/GUIViewStatePictures.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStatePictures.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/pictures/GUIWindowPictures.cpp b/xbmc/pictures/GUIWindowPictures.cpp
index 2abc2a459a..b7345526fd 100644
--- a/xbmc/pictures/GUIWindowPictures.cpp
+++ b/xbmc/pictures/GUIWindowPictures.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogPictureInfo.h"
#include "GUIPassword.h"
#include "GUIWindowSlideShow.h"
diff --git a/xbmc/pictures/GUIWindowSlideShow.cpp b/xbmc/pictures/GUIWindowSlideShow.cpp
index 59ddf28061..4a47726dc8 100644
--- a/xbmc/pictures/GUIWindowSlideShow.cpp
+++ b/xbmc/pictures/GUIWindowSlideShow.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowSlideShow.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogPictureInfo.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
diff --git a/xbmc/pictures/PictureFolderImageFileLoader.cpp b/xbmc/pictures/PictureFolderImageFileLoader.cpp
index 1eb58f21b0..b80749b086 100644
--- a/xbmc/pictures/PictureFolderImageFileLoader.cpp
+++ b/xbmc/pictures/PictureFolderImageFileLoader.cpp
@@ -9,6 +9,7 @@
#include "PictureFolderImageFileLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "Picture.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
diff --git a/xbmc/pictures/PictureInfoLoader.cpp b/xbmc/pictures/PictureInfoLoader.cpp
index 2a62807055..14a880bcec 100644
--- a/xbmc/pictures/PictureInfoLoader.cpp
+++ b/xbmc/pictures/PictureInfoLoader.cpp
@@ -9,6 +9,7 @@
#include "PictureInfoLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PictureInfoTag.h"
#include "ServiceBroker.h"
#include "settings/Settings.h"
diff --git a/xbmc/pictures/PictureThumbLoader.cpp b/xbmc/pictures/PictureThumbLoader.cpp
index 8e1a6bc95d..0745c6e3ca 100644
--- a/xbmc/pictures/PictureThumbLoader.cpp
+++ b/xbmc/pictures/PictureThumbLoader.cpp
@@ -9,6 +9,7 @@
#include "PictureThumbLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "Picture.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
diff --git a/xbmc/platform/android/activity/CMakeLists.txt b/xbmc/platform/android/activity/CMakeLists.txt
index fddcec8525..55714df929 100644
--- a/xbmc/platform/android/activity/CMakeLists.txt
+++ b/xbmc/platform/android/activity/CMakeLists.txt
@@ -16,6 +16,7 @@ set(SOURCES android_main.cpp
JNIXBMCNsdManagerResolveListener.cpp
JNIXBMCJsonHandler.cpp
JNIXBMCFile.cpp
+ JNIXBMCTextureCache.cpp
JNIXBMCURIUtils.cpp
JNIXBMCDisplayManagerDisplayListener.cpp
JNIXBMCSpeechRecognitionListener.cpp
@@ -42,6 +43,7 @@ set(HEADERS AndroidFeatures.h
JNIXBMCNsdManagerResolveListener.h
JNIXBMCJsonHandler.h
JNIXBMCFile.h
+ JNIXBMCTextureCache.h
JNIXBMCURIUtils.h
JNIXBMCDisplayManagerDisplayListener.h
JNIXBMCSpeechRecognitionListener.h
diff --git a/xbmc/platform/android/activity/JNIXBMCTextureCache.cpp b/xbmc/platform/android/activity/JNIXBMCTextureCache.cpp
new file mode 100644
index 0000000000..bacb4a826d
--- /dev/null
+++ b/xbmc/platform/android/activity/JNIXBMCTextureCache.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "JNIXBMCTextureCache.h"
+
+#include "CompileInfo.h"
+#include "TextureCache.h"
+
+#include <androidjni/Context.h>
+#include <androidjni/jutils-details.hpp>
+
+using namespace jni;
+
+static std::string s_className = std::string(CCompileInfo::GetClass()) + "/XBMCTextureCache";
+
+void CJNIXBMCTextureCache::RegisterNatives(JNIEnv* env)
+{
+ jclass cClass = env->FindClass(s_className.c_str());
+ if (cClass)
+ {
+ JNINativeMethod methods[] = {
+ {"_unwrapImageURL", "(Ljava/lang/String;)Ljava/lang/String;",
+ (void*)&CJNIXBMCTextureCache::_unwrapImageURL},
+ };
+
+ env->RegisterNatives(cClass, methods, sizeof(methods) / sizeof(methods[0]));
+ }
+}
+
+jstring CJNIXBMCTextureCache::_unwrapImageURL(JNIEnv* env, jobject thiz, jstring image)
+{
+ std::string strImage = jcast<std::string>(jhstring::fromJNI(image));
+ std::string responseData = CTextureUtils::UnwrapImageURL(strImage);
+
+ jstring jres = env->NewStringUTF(responseData.c_str());
+ return jres;
+}
diff --git a/xbmc/platform/android/activity/JNIXBMCTextureCache.h b/xbmc/platform/android/activity/JNIXBMCTextureCache.h
new file mode 100644
index 0000000000..92da6e91d5
--- /dev/null
+++ b/xbmc/platform/android/activity/JNIXBMCTextureCache.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include <androidjni/JNIBase.h>
+
+namespace jni
+{
+
+class CJNIXBMCTextureCache : public CJNIBase
+{
+public:
+ CJNIXBMCTextureCache(const jni::jhobject& object) : CJNIBase(object) {}
+
+ static void RegisterNatives(JNIEnv* env);
+
+protected:
+ ~CJNIXBMCTextureCache() override = default;
+
+ static jstring _unwrapImageURL(JNIEnv* env, jobject thiz, jstring image);
+};
+
+} // namespace jni
diff --git a/xbmc/platform/android/activity/android_main.cpp b/xbmc/platform/android/activity/android_main.cpp
index 3970e78f49..a934b6ee1c 100644
--- a/xbmc/platform/android/activity/android_main.cpp
+++ b/xbmc/platform/android/activity/android_main.cpp
@@ -23,6 +23,7 @@
#include "platform/android/activity/JNIXBMCNsdManagerResolveListener.h"
#include "platform/android/activity/JNIXBMCSpeechRecognitionListener.h"
#include "platform/android/activity/JNIXBMCSurfaceTextureOnFrameAvailableListener.h"
+#include "platform/android/activity/JNIXBMCTextureCache.h"
#include "platform/android/activity/JNIXBMCURIUtils.h"
#include "platform/android/activity/JNIXBMCVideoView.h"
@@ -127,6 +128,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
CJNIXBMCNsdManagerResolveListener::RegisterNatives(env);
CJNIXBMCSpeechRecognitionListener::RegisterNatives(env);
CJNIXBMCSurfaceTextureOnFrameAvailableListener::RegisterNatives(env);
+ CJNIXBMCTextureCache::RegisterNatives(env);
CJNIXBMCURIUtils::RegisterNatives(env);
CJNIXBMCVideoView::RegisterNatives(env);
diff --git a/xbmc/platform/android/filesystem/APKDirectory.cpp b/xbmc/platform/android/filesystem/APKDirectory.cpp
index df890bfed6..4cdcf5c529 100644
--- a/xbmc/platform/android/filesystem/APKDirectory.cpp
+++ b/xbmc/platform/android/filesystem/APKDirectory.cpp
@@ -10,6 +10,7 @@
#include "APKFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp b/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp
index c2af2aae47..132f666618 100644
--- a/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp
+++ b/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp
@@ -10,6 +10,7 @@
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/File.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/platform/darwin/tvos/TVOSTopShelf.mm b/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
index 94690fea00..fb4770f5cd 100644
--- a/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
+++ b/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
@@ -10,6 +10,7 @@
#include "DatabaseManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "application/Application.h"
#include "filesystem/File.h"
diff --git a/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp b/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp
index 0463943505..d0d25df5d6 100644
--- a/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp
+++ b/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp
@@ -21,6 +21,7 @@
#include "TVOSDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/SpecialProtocol.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/platform/posix/filesystem/PosixDirectory.cpp b/xbmc/platform/posix/filesystem/PosixDirectory.cpp
index 6685c0e1db..761b8d53b4 100644
--- a/xbmc/platform/posix/filesystem/PosixDirectory.cpp
+++ b/xbmc/platform/posix/filesystem/PosixDirectory.cpp
@@ -9,6 +9,7 @@
#include "PosixDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/AliasShortcutUtils.h"
#include "utils/CharsetConverter.h"
diff --git a/xbmc/platform/posix/filesystem/SMBDirectory.cpp b/xbmc/platform/posix/filesystem/SMBDirectory.cpp
index e2305afb4a..12fe62683e 100644
--- a/xbmc/platform/posix/filesystem/SMBDirectory.cpp
+++ b/xbmc/platform/posix/filesystem/SMBDirectory.cpp
@@ -20,6 +20,7 @@
#include "SMBDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PasswordManager.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp b/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp
index 8bab0aa9e9..c2f247da10 100644
--- a/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp
+++ b/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp
@@ -9,6 +9,7 @@
#include "SMBWSDiscovery.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "network/IWSDiscovery.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp b/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp
index bba7074400..4bd0a0db4c 100644
--- a/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp
+++ b/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp
@@ -9,6 +9,7 @@
#include "WinLibraryDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/platform/win32/filesystem/Win32Directory.cpp b/xbmc/platform/win32/filesystem/Win32Directory.cpp
index 5e4050fdd4..3d06e8dfbc 100644
--- a/xbmc/platform/win32/filesystem/Win32Directory.cpp
+++ b/xbmc/platform/win32/filesystem/Win32Directory.cpp
@@ -9,6 +9,7 @@
#include "Win32Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/CharsetConverter.h"
#include "utils/SystemInfo.h"
diff --git a/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp b/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp
index 2075f957c8..c227351ad4 100644
--- a/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp
+++ b/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp
@@ -9,6 +9,7 @@
#include "Win32SMBDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PasswordManager.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/playlists/PlayList.cpp b/xbmc/playlists/PlayList.cpp
index 82031bad2e..b47c782541 100644
--- a/xbmc/playlists/PlayList.cpp
+++ b/xbmc/playlists/PlayList.cpp
@@ -9,6 +9,7 @@
#include "PlayList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PlayListFactory.h"
#include "ServiceBroker.h"
#include "filesystem/File.h"
diff --git a/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp b/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp
index 7249bb5c0d..443dabcd4e 100644
--- a/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp
+++ b/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp
@@ -9,6 +9,7 @@
#include "SmartPlaylistFileItemListModifier.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "playlists/SmartPlayList.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp b/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp
index dcdf8c47a4..9f455c4a6b 100644
--- a/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp
+++ b/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogProfileSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp b/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp
index d3690adb63..503516c0f6 100644
--- a/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp
+++ b/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowSettingsProfile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogSelect.h"
diff --git a/xbmc/programs/GUIViewStatePrograms.cpp b/xbmc/programs/GUIViewStatePrograms.cpp
index 05e4cfd978..0b08a42864 100644
--- a/xbmc/programs/GUIViewStatePrograms.cpp
+++ b/xbmc/programs/GUIViewStatePrograms.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStatePrograms.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/programs/GUIWindowPrograms.cpp b/xbmc/programs/GUIWindowPrograms.cpp
index 862bdb2249..7a57f1cc0b 100644
--- a/xbmc/programs/GUIWindowPrograms.cpp
+++ b/xbmc/programs/GUIWindowPrograms.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp b/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp
index e539ca55bd..b66ef00902 100644
--- a/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp
+++ b/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp
@@ -9,6 +9,7 @@
#include "PVRChannelGroupImageFileLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/PVRGUIDirectory.h"
#include "guilib/Texture.h"
#include "pictures/Picture.h"
diff --git a/xbmc/pvr/PVRThumbLoader.cpp b/xbmc/pvr/PVRThumbLoader.cpp
index 3f5fa63822..8f41a80b0c 100644
--- a/xbmc/pvr/PVRThumbLoader.cpp
+++ b/xbmc/pvr/PVRThumbLoader.cpp
@@ -9,6 +9,7 @@
#include "PVRThumbLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "pvr/PVRManager.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
index b057b338bc..563aa126cd 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRChannelGuide.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/PVRPlaybackState.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
index d6665fcf4b..efae8e7279 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRChannelManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
index 9c079c8e7e..c349bd0623 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRChannelsOSD.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
index c0d6d801d7..1fa8cd5175 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRGroupManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogYesNo.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp b/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp
index 2add783cf2..72b4694528 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "input/actions/Action.h"
diff --git a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
index 8def92d871..2b15428347 100644
--- a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
+++ b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
#include "guilib/WindowIDs.h"
diff --git a/xbmc/pvr/guilib/GUIEPGGridContainer.cpp b/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
index de3ef1059e..d990f3f9db 100644
--- a/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
+++ b/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
@@ -9,6 +9,7 @@
#include "GUIEPGGridContainer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/DirtyRegion.h"
#include "guilib/GUIAction.h"
diff --git a/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp b/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp
index f99515160c..df6f7e41cd 100644
--- a/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp
+++ b/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp
@@ -9,6 +9,7 @@
#include "GUIEPGGridContainerModel.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannel.h"
diff --git a/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp b/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
index 53bbf815f6..1bf613dc4e 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsDatabase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogProgress.h"
#include "dialogs/GUIDialogSelect.h"
diff --git a/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp b/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp
index 15c8af4208..ed11f9ec2a 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsPlayback.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "application/ApplicationEnums.h"
#include "cores/DataCacheCore.h"
diff --git a/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp b/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp
index c69c909b9a..9609617be9 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsRecordings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "dialogs/GUIDialogBusy.h"
diff --git a/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp b/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp
index 907c645dd3..c6399f1a26 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "pvr/PVRManager.h"
diff --git a/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp b/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp
index 26859dd63a..11045c98d8 100644
--- a/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp
+++ b/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIChannelIconUpdater.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/pvr/windows/GUIViewStatePVR.cpp b/xbmc/pvr/windows/GUIViewStatePVR.cpp
index d86f6fc2a6..a5004d8ba9 100644
--- a/xbmc/pvr/windows/GUIViewStatePVR.cpp
+++ b/xbmc/pvr/windows/GUIViewStatePVR.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStatePVR.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClients.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
index 71a800feda..ce891a80f7 100644
--- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRBase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
index e323c319be..8ccbdd68fa 100644
--- a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRChannels.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index 3923cae6bb..6ce75fd5f2 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRGuide.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "addons/Skin.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp
index 363011a379..284bebb93e 100644
--- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp
@@ -8,6 +8,7 @@
#include "GUIWindowPVRRecordings.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
index 0c129c3e00..4a9ad6b10e 100644
--- a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRSearch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogBusy.h"
#include "dialogs/GUIDialogYesNo.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp b/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp
index 1b203d403d..1d532fa1ac 100644
--- a/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRTimerRules.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "pvr/timers/PVRTimersPath.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRTimers.cpp b/xbmc/pvr/windows/GUIWindowPVRTimers.cpp
index 610571bcd5..0bc955d6c8 100644
--- a/xbmc/pvr/windows/GUIWindowPVRTimers.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRTimers.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRTimers.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "pvr/timers/PVRTimersPath.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp b/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp
index 41677eb873..68b1501e2b 100644
--- a/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRTimersBase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/rendering/gles/GLESShader.cpp b/xbmc/rendering/gles/GLESShader.cpp
index 961c3f7961..ba7b83175d 100644
--- a/xbmc/rendering/gles/GLESShader.cpp
+++ b/xbmc/rendering/gles/GLESShader.cpp
@@ -54,6 +54,9 @@ void CGLESShader::OnCompiledAndLinked()
m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
m_hCoord0Matrix = glGetUniformLocation(ProgramHandle(), "m_coord0Matrix");
+ m_hMatrix = glGetUniformLocation(ProgramHandle(), "m_matrix");
+ m_hShaderClip = glGetUniformLocation(ProgramHandle(), "m_shaderClip");
+ m_hCoordStep = glGetUniformLocation(ProgramHandle(), "m_cordStep");
// Vertex attributes
m_hPos = glGetAttribLocation(ProgramHandle(), "m_attrpos");
diff --git a/xbmc/rendering/gles/GLESShader.h b/xbmc/rendering/gles/GLESShader.h
index 1f59895740..ddc31202c5 100644
--- a/xbmc/rendering/gles/GLESShader.h
+++ b/xbmc/rendering/gles/GLESShader.h
@@ -32,6 +32,9 @@ public:
GLint GetContrastLoc() { return m_hContrast; }
GLint GetBrightnessLoc() { return m_hBrightness; }
GLint GetModelLoc() { return m_hModel; }
+ GLint GetMatrixLoc() { return m_hMatrix; }
+ GLint GetShaderClipLoc() { return m_hShaderClip; }
+ GLint GetShaderCoordStepLoc() { return m_hCoordStep; }
bool HardwareClipIsPossible() { return m_clipPossible; }
GLfloat GetClipXFactor() { return m_clipXFactor; }
GLfloat GetClipXOffset() { return m_clipXOffset; }
@@ -44,6 +47,9 @@ protected:
GLint m_hUniCol = 0;
GLint m_hProj = 0;
GLint m_hModel = 0;
+ GLint m_hMatrix{0}; // m_hProj * m_hModel
+ GLint m_hShaderClip{0}; // clipping rect vec4(x1,y1,x2,y2)
+ GLint m_hCoordStep{0}; // step (1/resolution) for the two textures vec4(t1.x,t1.y,t2.x,t2.y)
GLint m_hPos = 0;
GLint m_hCol = 0;
GLint m_hCord0 = 0;
diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp
index f25f783960..a5c02803b0 100644
--- a/xbmc/rendering/gles/RenderSystemGLES.cpp
+++ b/xbmc/rendering/gles/RenderSystemGLES.cpp
@@ -425,7 +425,7 @@ void CRenderSystemGLES::InitialiseShaders()
}
m_pShader[ShaderMethodGLES::SM_FONTS] =
- std::make_unique<CGLESShader>("gles_shader_fonts.frag", defines);
+ std::make_unique<CGLESShader>("gles_shader_simple.vert", "gles_shader_fonts.frag", defines);
if (!m_pShader[ShaderMethodGLES::SM_FONTS]->CompileAndLink())
{
m_pShader[ShaderMethodGLES::SM_FONTS]->Free();
@@ -433,6 +433,16 @@ void CRenderSystemGLES::InitialiseShaders()
CLog::Log(LOGERROR, "GUI Shader gles_shader_fonts.frag - compile and link failed");
}
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP] =
+ std::make_unique<CGLESShader>("gles_shader_clip.vert", "gles_shader_fonts.frag", defines);
+ if (!m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP]->CompileAndLink())
+ {
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP].reset();
+ CLog::Log(LOGERROR, "GUI Shader gles_shader_clip.vert + gles_shader_fonts.frag - compile "
+ "and link failed");
+ }
+
m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND] =
std::make_unique<CGLESShader>("gles_shader_texture_noblend.frag", defines);
if (!m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND]->CompileAndLink())
@@ -528,6 +538,10 @@ void CRenderSystemGLES::ReleaseShaders()
m_pShader[ShaderMethodGLES::SM_FONTS]->Free();
m_pShader[ShaderMethodGLES::SM_FONTS].reset();
+ if (m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP])
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP].reset();
+
if (m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND])
m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND]->Free();
m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND].reset();
@@ -675,3 +689,27 @@ GLint CRenderSystemGLES::GUIShaderGetModel()
return -1;
}
+
+GLint CRenderSystemGLES::GUIShaderGetMatrix()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetMatrixLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGLES::GUIShaderGetClip()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderClipLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGLES::GUIShaderGetCoordStep()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderCoordStepLoc();
+
+ return -1;
+}
diff --git a/xbmc/rendering/gles/RenderSystemGLES.h b/xbmc/rendering/gles/RenderSystemGLES.h
index e0cd72b9c1..7986f2c0a4 100644
--- a/xbmc/rendering/gles/RenderSystemGLES.h
+++ b/xbmc/rendering/gles/RenderSystemGLES.h
@@ -25,6 +25,7 @@ enum class ShaderMethodGLES
SM_TEXTURE,
SM_MULTI,
SM_FONTS,
+ SM_FONTS_SHADER_CLIP,
SM_TEXTURE_NOBLEND,
SM_MULTI_BLENDCOLOR,
SM_TEXTURE_RGBA,
@@ -55,6 +56,7 @@ private:
{ShaderMethodGLES::SM_TEXTURE, "texture"},
{ShaderMethodGLES::SM_MULTI, "multi"},
{ShaderMethodGLES::SM_FONTS, "fonts"},
+ {ShaderMethodGLES::SM_FONTS_SHADER_CLIP, "fonts with vertex shader based clipping"},
{ShaderMethodGLES::SM_TEXTURE_NOBLEND, "texture no blending"},
{ShaderMethodGLES::SM_MULTI_BLENDCOLOR, "multi blend colour"},
{ShaderMethodGLES::SM_TEXTURE_RGBA, "texure rgba"},
@@ -124,6 +126,9 @@ public:
GLint GUIShaderGetContrast();
GLint GUIShaderGetBrightness();
GLint GUIShaderGetModel();
+ GLint GUIShaderGetMatrix();
+ GLint GUIShaderGetClip();
+ GLint GUIShaderGetCoordStep();
protected:
virtual void SetVSyncImpl(bool enable) = 0;
diff --git a/xbmc/settings/windows/GUIControlSettings.cpp b/xbmc/settings/windows/GUIControlSettings.cpp
index fdb1a439fd..ea45b0deed 100644
--- a/xbmc/settings/windows/GUIControlSettings.cpp
+++ b/xbmc/settings/windows/GUIControlSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIControlSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/test/TestBasicEnvironment.cpp b/xbmc/test/TestBasicEnvironment.cpp
index 7a357765a0..7a33e9d851 100644
--- a/xbmc/test/TestBasicEnvironment.cpp
+++ b/xbmc/test/TestBasicEnvironment.cpp
@@ -9,6 +9,7 @@
#include "TestBasicEnvironment.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "ServiceManager.h"
#include "TestUtils.h"
diff --git a/xbmc/utils/FileOperationJob.h b/xbmc/utils/FileOperationJob.h
index 7284c62b6b..5dad5403bd 100644
--- a/xbmc/utils/FileOperationJob.h
+++ b/xbmc/utils/FileOperationJob.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/IFileTypes.h"
#include "utils/ProgressJob.h"
diff --git a/xbmc/utils/FontUtils.cpp b/xbmc/utils/FontUtils.cpp
index 2c23b90c69..8e6af68907 100644
--- a/xbmc/utils/FontUtils.cpp
+++ b/xbmc/utils/FontUtils.cpp
@@ -9,6 +9,7 @@
#include "FontUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "StringUtils.h"
#include "URIUtils.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/utils/GroupUtils.cpp b/xbmc/utils/GroupUtils.cpp
index c44af798f5..348b574880 100644
--- a/xbmc/utils/GroupUtils.cpp
+++ b/xbmc/utils/GroupUtils.cpp
@@ -9,6 +9,7 @@
#include "GroupUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/MultiPathDirectory.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/utils/RecentlyAddedJob.cpp b/xbmc/utils/RecentlyAddedJob.cpp
index fca1f6d997..3a845ac2ac 100644
--- a/xbmc/utils/RecentlyAddedJob.cpp
+++ b/xbmc/utils/RecentlyAddedJob.cpp
@@ -9,6 +9,7 @@
#include "RecentlyAddedJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindow.h"
diff --git a/xbmc/utils/SaveFileStateJob.cpp b/xbmc/utils/SaveFileStateJob.cpp
index aeb479a4bb..d2886f640e 100644
--- a/xbmc/utils/SaveFileStateJob.cpp
+++ b/xbmc/utils/SaveFileStateJob.cpp
@@ -38,15 +38,24 @@ void CSaveFileState::DoWork(CFileItem& item,
{
std::string progressTrackingFile = item.GetPath();
- if (item.HasVideoInfoTag() && StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://"))
- progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified
+ if (item.HasVideoInfoTag() &&
+ StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://"))
+ progressTrackingFile =
+ item.GetVideoInfoTag()
+ ->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified
+ else if (IsBlurayPlaylist(item) && (item.GetVideoContentType() == VideoDbContentType::MOVIES ||
+ item.GetVideoContentType() == VideoDbContentType::EPISODES))
+ progressTrackingFile = item.GetDynPath();
else if (item.HasVideoInfoTag() && IsVideoDb(item))
- progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // we need the file url of the video db item to create the bookmark
+ progressTrackingFile =
+ item.GetVideoInfoTag()
+ ->m_strFileNameAndPath; // we need the file url of the video db item to create the bookmark
else if (item.HasProperty("original_listitem_url"))
{
// only use original_listitem_url for Python, UPnP and Bluray sources
std::string original = item.GetProperty("original_listitem_url").asString();
- if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(item.GetPath()))
+ if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) ||
+ URIUtils::IsBluray(item.GetPath()))
progressTrackingFile = original;
}
@@ -162,7 +171,14 @@ void CSaveFileState::DoWork(CFileItem& item,
if (!videodatabase.GetStreamDetails(dbItem) ||
dbItem.GetVideoInfoTag()->m_streamDetails != item.GetVideoInfoTag()->m_streamDetails)
{
- videodatabase.SetStreamDetailsForFile(item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile);
+ const int idFile = videodatabase.SetStreamDetailsForFile(
+ item.GetVideoInfoTag()->m_streamDetails, item.GetDynPath());
+ if (item.GetVideoContentType() == VideoDbContentType::MOVIES)
+ videodatabase.SetFileForMovie(item.GetDynPath(), item.GetVideoInfoTag()->m_iDbId,
+ idFile);
+ else if (item.GetVideoContentType() == VideoDbContentType::EPISODES)
+ videodatabase.SetFileForEpisode(item.GetDynPath(), item.GetVideoInfoTag()->m_iDbId,
+ idFile);
updateListing = true;
}
}
diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp
index ca65b57b65..9b862a7f43 100644
--- a/xbmc/utils/URIUtils.cpp
+++ b/xbmc/utils/URIUtils.cpp
@@ -6,19 +6,21 @@
* See LICENSES/README.md for more information.
*/
-#include "network/Network.h"
#include "URIUtils.h"
+
#include "FileItem.h"
+#include "FileItemList.h"
+#include "ServiceBroker.h"
+#include "StringUtils.h"
+#include "URL.h"
#include "filesystem/MultiPathDirectory.h"
#include "filesystem/SpecialProtocol.h"
#include "filesystem/StackDirectory.h"
#include "network/DNSNameCache.h"
+#include "network/Network.h"
#include "pvr/channels/PVRChannelsPath.h"
#include "settings/AdvancedSettings.h"
-#include "URL.h"
#include "utils/FileExtensionProvider.h"
-#include "ServiceBroker.h"
-#include "StringUtils.h"
#include "utils/log.h"
#if defined(TARGET_WINDOWS)
diff --git a/xbmc/utils/test/TestVariant.cpp b/xbmc/utils/test/TestVariant.cpp
index f5bf687ea6..60eafddf04 100644
--- a/xbmc/utils/test/TestVariant.cpp
+++ b/xbmc/utils/test/TestVariant.cpp
@@ -294,7 +294,7 @@ TEST(TestVariant, empty)
std::map<std::string, std::string> strmap;
EXPECT_TRUE(CVariant(strmap).empty());
- strmap.emplace(std::string("key"), std::string("value"));
+ strmap.emplace("key", "value");
EXPECT_FALSE(CVariant(strmap).empty());
std::string str;
diff --git a/xbmc/video/ContextMenus.cpp b/xbmc/video/ContextMenus.cpp
index 94810a4c7b..1ab69f504e 100644
--- a/xbmc/video/ContextMenus.cpp
+++ b/xbmc/video/ContextMenus.cpp
@@ -240,7 +240,7 @@ bool CVideoChooseVersion::IsVisible(const CFileItem& item) const
return item.HasVideoVersions() &&
!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_VIDEOLIBRARY_SHOWVIDEOVERSIONSASFOLDER) &&
- !VIDEO::IsVideoAssetFile(item);
+ !IsVideoAssetFile(item);
}
bool CVideoChooseVersion::Execute(const std::shared_ptr<CFileItem>& item) const
@@ -434,7 +434,7 @@ bool CVideoPlayUsing::IsVisible(const CFileItem& item) const
if (item.HasVideoVersions() &&
!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_VIDEOLIBRARY_SHOWVIDEOVERSIONSASFOLDER) &&
- !VIDEO::IsVideoAssetFile(item))
+ !IsVideoAssetFile(item))
return false;
if (item.IsLiveTV())
@@ -456,7 +456,7 @@ bool CVideoPlayVersionUsing::IsVisible(const CFileItem& item) const
return item.HasVideoVersions() &&
!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_VIDEOLIBRARY_SHOWVIDEOVERSIONSASFOLDER) &&
- !VIDEO::IsVideoAssetFile(item);
+ !IsVideoAssetFile(item);
}
bool CVideoPlayVersionUsing::Execute(const std::shared_ptr<CFileItem>& itemIn) const
diff --git a/xbmc/video/GUIViewStateVideo.cpp b/xbmc/video/GUIViewStateVideo.cpp
index a33eb260f4..1cf1a0115c 100644
--- a/xbmc/video/GUIViewStateVideo.cpp
+++ b/xbmc/video/GUIViewStateVideo.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateVideo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "VideoDatabase.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp
index a0e0046b08..a0b05561db 100644
--- a/xbmc/video/VideoDatabase.cpp
+++ b/xbmc/video/VideoDatabase.cpp
@@ -9,6 +9,7 @@
#include "VideoDatabase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
@@ -3019,6 +3020,49 @@ int CVideoDatabase::SetDetailsForSeason(const CVideoInfoTag& details, const std:
return -1;
}
+bool CVideoDatabase::SetFileForEpisode(const std::string& fileAndPath, int idEpisode, int idFile)
+{
+ try
+ {
+ BeginTransaction();
+ std::string sql = PrepareSQL("UPDATE episode SET c18='%s', idFile=%i WHERE idEpisode=%i",
+ fileAndPath.c_str(), idFile, idEpisode);
+ m_pDS->exec(sql);
+ CommitTransaction();
+
+ return true;
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "{} ({}) failed", __FUNCTION__, idEpisode);
+ }
+ RollbackTransaction();
+ return false;
+}
+
+bool CVideoDatabase::SetFileForMovie(const std::string& fileAndPath, int idMovie, int idFile)
+{
+ try
+ {
+ BeginTransaction();
+ std::string sql = PrepareSQL("UPDATE movie SET c22='%s', idFile=%i WHERE idMovie=%i",
+ fileAndPath.c_str(), idFile, idMovie);
+ m_pDS->exec(sql);
+ sql = PrepareSQL("UPDATE videoversion SET idFile=%i WHERE idMedia=%i AND media_type='movie'",
+ idFile, idMovie);
+ m_pDS->exec(sql);
+ CommitTransaction();
+
+ return true;
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "{} ({}) failed", __FUNCTION__, idMovie);
+ }
+ RollbackTransaction();
+ return false;
+}
+
int CVideoDatabase::SetDetailsForEpisode(CVideoInfoTag& details,
const std::map<std::string, std::string>& artwork,
int idShow,
@@ -3208,13 +3252,15 @@ int CVideoDatabase::SetDetailsForMusicVideo(CVideoInfoTag& details,
return -1;
}
-void CVideoDatabase::SetStreamDetailsForFile(const CStreamDetails& details, const std::string &strFileNameAndPath)
+int CVideoDatabase::SetStreamDetailsForFile(const CStreamDetails& details,
+ const std::string& strFileNameAndPath)
{
// AddFile checks to make sure the file isn't already in the DB first
int idFile = AddFile(strFileNameAndPath);
if (idFile < 0)
- return;
+ return -1;
SetStreamDetailsForFileId(details, idFile);
+ return idFile;
}
void CVideoDatabase::SetStreamDetailsForFileId(const CStreamDetails& details, int idFile)
@@ -4174,7 +4220,6 @@ bool CVideoDatabase::GetStreamDetails(CFileItem& item)
if (item.HasVideoInfoTag())
fileId = item.GetVideoInfoTag()->m_iFileId;
-
if (fileId < 0)
fileId = GetFileId(item);
@@ -4186,9 +4231,17 @@ bool CVideoDatabase::GetStreamDetails(CFileItem& item)
return GetStreamDetails(*item.GetVideoInfoTag());
}
-bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag) const
+bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag)
{
- if (tag.m_iFileId < 0)
+
+ const std::string path = tag.m_strFileNameAndPath;
+ int fileId{-1};
+ if (URIUtils::GetExtension(path) == ".mpls")
+ fileId = GetFileId(path);
+ else
+ fileId = tag.m_iFileId;
+
+ if (fileId < 0)
return false;
bool retVal = false;
@@ -4199,7 +4252,7 @@ bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag) const
std::unique_ptr<Dataset> pDS(m_pDB->CreateDataset());
try
{
- std::string strSQL = PrepareSQL("SELECT * FROM streamdetails WHERE idFile = %i", tag.m_iFileId);
+ std::string strSQL = PrepareSQL("SELECT * FROM streamdetails WHERE idFile = %i", fileId);
pDS->query(strSQL);
while (!pDS->eof())
@@ -6529,7 +6582,10 @@ int CVideoDatabase::GetPlayCount(const std::string& strFilenameAndPath)
int CVideoDatabase::GetPlayCount(const CFileItem &item)
{
- return GetPlayCount(GetFileId(item));
+ if (IsBlurayPlaylist(item))
+ return GetPlayCount(GetFileId(item.GetDynPath()));
+ else
+ return GetPlayCount(GetFileId(item));
}
CDateTime CVideoDatabase::GetLastPlayed(int iFileId)
@@ -6599,9 +6655,11 @@ void CVideoDatabase::UpdateFanart(const CFileItem& item, VideoDbContentType type
CDateTime CVideoDatabase::SetPlayCount(const CFileItem& item, int count, const CDateTime& date)
{
- int id;
- if (item.HasProperty("original_listitem_url") &&
- URIUtils::IsPlugin(item.GetProperty("original_listitem_url").asString()))
+ int id{-1};
+ if (IsBlurayPlaylist(item))
+ id = AddFile(item.GetDynPath());
+ else if (item.HasProperty("original_listitem_url") &&
+ URIUtils::IsPlugin(item.GetProperty("original_listitem_url").asString()))
{
CFileItem item2(item);
item2.SetPath(item.GetProperty("original_listitem_url").asString());
diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h
index aa0bee416d..a8b2bce51b 100644
--- a/xbmc/video/VideoDatabase.h
+++ b/xbmc/video/VideoDatabase.h
@@ -584,10 +584,12 @@ public:
const std::map<std::string, std::string>& artwork,
int idShow,
int idEpisode = -1);
+ bool SetFileForEpisode(const std::string& fileAndPath, int idEpisode, int idFile);
+ bool SetFileForMovie(const std::string& fileAndPath, int idMovie, int idFile);
int SetDetailsForMusicVideo(CVideoInfoTag& details,
const std::map<std::string, std::string>& artwork,
int idMVideo = -1);
- void SetStreamDetailsForFile(const CStreamDetails& details, const std::string &strFileNameAndPath);
+ int SetStreamDetailsForFile(const CStreamDetails& details, const std::string& strFileNameAndPath);
void SetStreamDetailsForFileId(const CStreamDetails& details, int idFile);
bool SetSingleValue(VideoDbContentType type, int dbId, int dbField, const std::string& strValue);
@@ -686,7 +688,7 @@ public:
void DeleteBookMarkForEpisode(const CVideoInfoTag& tag);
bool GetResumePoint(CVideoInfoTag& tag);
bool GetStreamDetails(CFileItem& item);
- bool GetStreamDetails(CVideoInfoTag& tag) const;
+ bool GetStreamDetails(CVideoInfoTag& tag);
bool GetDetailsByTypeAndId(CFileItem& item, VideoDbContentType type, int id);
CVideoInfoTag GetDetailsByTypeAndId(VideoDbContentType type, int id);
diff --git a/xbmc/video/VideoFileItemClassify.cpp b/xbmc/video/VideoFileItemClassify.cpp
index 64c3935b3c..afeaafcb65 100644
--- a/xbmc/video/VideoFileItemClassify.cpp
+++ b/xbmc/video/VideoFileItemClassify.cpp
@@ -10,6 +10,7 @@
#include "FileItem.h"
#include "ServiceBroker.h"
+#include "URL.h"
#include "utils/FileExtensionProvider.h"
#include "utils/FileUtils.h"
#include "utils/StringUtils.h"
@@ -71,6 +72,11 @@ bool IsProtectedBlurayDisc(const CFileItem& item)
return CFileUtils::Exists(path);
}
+bool IsBlurayPlaylist(const CFileItem& item)
+{
+ return StringUtils::EqualsNoCase(URIUtils::GetExtension(item.GetDynPath()), ".mpls");
+}
+
bool IsSubtitle(const CFileItem& item)
{
return URIUtils::HasExtension(item.GetPath(),
@@ -122,6 +128,16 @@ bool IsVideo(const CFileItem& item)
CServiceBroker::GetFileExtensionProvider().GetVideoExtensions());
}
+bool IsVideoAssetFile(const CFileItem& item)
+{
+ if (item.m_bIsFolder || !IsVideoDb(item))
+ return false;
+
+ // @todo maybe in the future look for prefix videodb://movies/videoversions in path instead
+ // @todo better encoding of video assets as path, they won't always be tied with movies.
+ return CURL(item.GetPath()).HasOption("videoversionid");
+}
+
bool IsVideoDb(const CFileItem& item)
{
return URIUtils::IsVideoDb(item.GetPath());
diff --git a/xbmc/video/VideoFileItemClassify.h b/xbmc/video/VideoFileItemClassify.h
index df9ff3445f..7a24113fde 100644
--- a/xbmc/video/VideoFileItemClassify.h
+++ b/xbmc/video/VideoFileItemClassify.h
@@ -25,6 +25,9 @@ bool IsDVDFile(const CFileItem& item, bool bVobs = true, bool bIfos = true);
//! \brief Checks whether item points to a protected blu-ray disc.
bool IsProtectedBlurayDisc(const CFileItem& item);
+//! \brief Checks whether item points to a blu-ray playlist (.mpls)
+bool IsBlurayPlaylist(const CFileItem& item);
+
//! \brief Check whether an item is a subtitle file.
bool IsSubtitle(const CFileItem& item);
@@ -33,6 +36,11 @@ bool IsSubtitle(const CFileItem& item);
//! so that may include eg. folders.
bool IsVideo(const CFileItem& item);
+//! \brief Is the item a video asset, excluding folders
+//! \param[in] item the item
+//! \return true if it is, false otherwise
+bool IsVideoAssetFile(const CFileItem& item);
+
//! \brief Check whether an item is a video database item.
bool IsVideoDb(const CFileItem& item);
diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp
index ba988d1a5b..b9062bf0b1 100644
--- a/xbmc/video/VideoInfoScanner.cpp
+++ b/xbmc/video/VideoInfoScanner.cpp
@@ -9,6 +9,7 @@
#include "VideoInfoScanner.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
diff --git a/xbmc/video/VideoItemArtworkHandler.cpp b/xbmc/video/VideoItemArtworkHandler.cpp
index 038da6b405..b845b52b4c 100644
--- a/xbmc/video/VideoItemArtworkHandler.cpp
+++ b/xbmc/video/VideoItemArtworkHandler.cpp
@@ -9,6 +9,7 @@
#include "VideoItemArtworkHandler.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MediaSource.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
diff --git a/xbmc/video/VideoThumbLoader.cpp b/xbmc/video/VideoThumbLoader.cpp
index d87a6c04ae..7119716136 100644
--- a/xbmc/video/VideoThumbLoader.cpp
+++ b/xbmc/video/VideoThumbLoader.cpp
@@ -9,6 +9,7 @@
#include "VideoThumbLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "URL.h"
@@ -413,7 +414,7 @@ bool CVideoThumbLoader::FillLibraryArt(CFileItem &item)
m_videoDatabase->Open();
// @todo unify asset path for other items path
- if (VIDEO::IsVideoAssetFile(item))
+ if (IsVideoAssetFile(item))
{
if (m_videoDatabase->GetArtForAsset(
tag.m_iFileId,
diff --git a/xbmc/video/VideoUtils.cpp b/xbmc/video/VideoUtils.cpp
index 2bfbd002b7..cc74cb0a0f 100644
--- a/xbmc/video/VideoUtils.cpp
+++ b/xbmc/video/VideoUtils.cpp
@@ -9,6 +9,7 @@
#include "VideoUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/video/dialogs/GUIDialogCMSSettings.cpp b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
index 6299cacbc6..c7945523ee 100644
--- a/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogCMSSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "addons/Skin.h"
diff --git a/xbmc/video/dialogs/GUIDialogSubtitles.cpp b/xbmc/video/dialogs/GUIDialogSubtitles.cpp
index e178a0002e..c22eda9717 100644
--- a/xbmc/video/dialogs/GUIDialogSubtitles.cpp
+++ b/xbmc/video/dialogs/GUIDialogSubtitles.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSubtitles.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
index a5cb7989da..9c086dc109 100644
--- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoBookmarks.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "Util.h"
diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
index 151c81620d..2585679c6e 100644
--- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
@@ -281,7 +282,7 @@ void CGUIDialogVideoInfo::OnInitWindow()
CONTROL_DISABLE(CONTROL_BTN_REFRESH);
// @todo add support to edit video asset art. Until then edit art through Versions Manager.
- if (!VIDEO::IsVideoAssetFile(*m_movieItem))
+ if (!IsVideoAssetFile(*m_movieItem))
CONTROL_ENABLE_ON_CONDITION(
CONTROL_BTN_GET_THUMB,
(profileManager->GetCurrentProfile().canWriteDatabases() ||
@@ -1081,18 +1082,18 @@ int CGUIDialogVideoInfo::ManageVideoItem(const std::shared_ptr<CFileItem>& item)
int dbId = item->GetVideoInfoTag()->m_iDbId;
CContextButtons buttons;
- if ((type == MediaTypeMovie && !VIDEO::IsVideoAssetFile(*item)) ||
- type == MediaTypeVideoCollection || type == MediaTypeTvShow || type == MediaTypeEpisode ||
+ if ((type == MediaTypeMovie && !IsVideoAssetFile(*item)) || type == MediaTypeVideoCollection ||
+ type == MediaTypeTvShow || type == MediaTypeEpisode ||
(type == MediaTypeSeason &&
item->GetVideoInfoTag()->m_iSeason > 0) || // seasons without "all seasons" and "specials"
type == MediaTypeMusicVideo)
buttons.Add(CONTEXT_BUTTON_EDIT, 16105);
- if ((type == MediaTypeMovie && !VIDEO::IsVideoAssetFile(*item)) || type == MediaTypeTvShow ||
+ if ((type == MediaTypeMovie && !IsVideoAssetFile(*item)) || type == MediaTypeTvShow ||
type == MediaTypeSeason)
buttons.Add(CONTEXT_BUTTON_EDIT_SORTTITLE, 16107);
- if (type == MediaTypeMovie && !VIDEO::IsVideoAssetFile(*item))
+ if (type == MediaTypeMovie && !IsVideoAssetFile(*item))
{
// only show link/unlink if there are tvshows available
if (database.HasContent(VideoDbContentType::TVSHOWS))
@@ -1116,9 +1117,8 @@ int CGUIDialogVideoInfo::ManageVideoItem(const std::shared_ptr<CFileItem>& item)
item->GetVideoInfoTag()->m_iBookmarkId > 0)
buttons.Add(CONTEXT_BUTTON_UNLINK_BOOKMARK, 20405);
- if (type == MediaTypeVideoCollection ||
- (type == MediaTypeMovie && !VIDEO::IsVideoAssetFile(*item)) || type == MediaTypeTvShow ||
- type == MediaTypeSeason || type == MediaTypeEpisode)
+ if (type == MediaTypeVideoCollection || (type == MediaTypeMovie && !IsVideoAssetFile(*item)) ||
+ type == MediaTypeTvShow || type == MediaTypeSeason || type == MediaTypeEpisode)
buttons.Add(CONTEXT_BUTTON_SET_ART, 13511);
// movie sets
@@ -1142,7 +1142,7 @@ int CGUIDialogVideoInfo::ManageVideoItem(const std::shared_ptr<CFileItem>& item)
}
}
- if (type != MediaTypeSeason && !VIDEO::IsVideoAssetFile(*item))
+ if (type != MediaTypeSeason && !IsVideoAssetFile(*item))
{
// Remove from library
buttons.Add(CONTEXT_BUTTON_DELETE, 646);
diff --git a/xbmc/video/dialogs/GUIDialogVideoManager.cpp b/xbmc/video/dialogs/GUIDialogVideoManager.cpp
index f5dc78b271..18c6d90562 100644
--- a/xbmc/video/dialogs/GUIDialogVideoManager.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoManager.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "MediaSource.h"
#include "ServiceBroker.h"
diff --git a/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp b/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp
index 28bae13d04..9f8206d44e 100644
--- a/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoManagerExtras.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp b/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp
index f2dada7087..f48c61ee67 100644
--- a/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoManagerVersions.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/video/guilib/VideoGUIUtils.cpp b/xbmc/video/guilib/VideoGUIUtils.cpp
index 763a13c07c..9cd5487828 100644
--- a/xbmc/video/guilib/VideoGUIUtils.cpp
+++ b/xbmc/video/guilib/VideoGUIUtils.cpp
@@ -9,6 +9,7 @@
#include "VideoGUIUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
diff --git a/xbmc/video/guilib/VideoSelectActionProcessor.cpp b/xbmc/video/guilib/VideoSelectActionProcessor.cpp
index 665b55858d..b3a84b1fb8 100644
--- a/xbmc/video/guilib/VideoSelectActionProcessor.cpp
+++ b/xbmc/video/guilib/VideoSelectActionProcessor.cpp
@@ -9,6 +9,7 @@
#include "VideoSelectActionProcessor.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogSelect.h"
diff --git a/xbmc/video/guilib/VideoVersionHelper.cpp b/xbmc/video/guilib/VideoVersionHelper.cpp
index 098aa50b7f..6a4923052b 100644
--- a/xbmc/video/guilib/VideoVersionHelper.cpp
+++ b/xbmc/video/guilib/VideoVersionHelper.cpp
@@ -9,6 +9,7 @@
#include "VideoVersionHelper.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "dialogs/GUIDialogSelect.h"
@@ -280,17 +281,3 @@ std::shared_ptr<CFileItem> CVideoVersionHelper::ChooseVideoFromAssets(
return item;
}
-
-bool VIDEO::IsVideoAssetFile(const CFileItem& item)
-{
- if (item.m_bIsFolder || !IsVideoDb(item))
- return false;
-
- // @todo maybe in the future look for prefix videodb://movies/videoversions in path instead
- // @todo better encoding of video assets as path, they won't always be tied with movies.
- const CURL itemUrl{item.GetPath()};
- if (itemUrl.HasOption("videoversionid"))
- return true;
-
- return false;
-}
diff --git a/xbmc/video/guilib/VideoVersionHelper.h b/xbmc/video/guilib/VideoVersionHelper.h
index 8d81ec1b65..b3ab15e503 100644
--- a/xbmc/video/guilib/VideoVersionHelper.h
+++ b/xbmc/video/guilib/VideoVersionHelper.h
@@ -23,11 +23,4 @@ public:
};
} // namespace GUILIB
-/*!
- * \brief Is the item a video asset, excluding folders
- * \param[in] item the item
- * \return true if it is, false otherwise
- */
-bool IsVideoAssetFile(const CFileItem& item);
-
} // namespace VIDEO
diff --git a/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp b/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp
index 486bd7a727..ef2e9253ad 100644
--- a/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp
+++ b/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp
@@ -9,6 +9,7 @@
#include "VideoLibraryMarkWatchedJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp b/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp
index 832bdd6b7f..ff0f7426fa 100644
--- a/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp
+++ b/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp
@@ -9,6 +9,7 @@
#include "VideoLibraryRefreshingJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
#include "URL.h"
diff --git a/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp b/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp
index 15b71a2955..1c9d2c768d 100644
--- a/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp
+++ b/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp
@@ -8,12 +8,13 @@
#include "VideoLibraryResetResumePointJob.h"
-#include <vector>
-
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/IDirectory.h"
+
+#include <vector>
#ifdef HAS_UPNP
#include "network/upnp/UPnP.h"
#endif
diff --git a/xbmc/video/tags/VideoTagLoaderNFO.cpp b/xbmc/video/tags/VideoTagLoaderNFO.cpp
index f85ce39818..c5e3b84539 100644
--- a/xbmc/video/tags/VideoTagLoaderNFO.cpp
+++ b/xbmc/video/tags/VideoTagLoaderNFO.cpp
@@ -9,6 +9,7 @@
#include "VideoTagLoaderNFO.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "NfoFile.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/video/tags/VideoTagLoaderPlugin.cpp b/xbmc/video/tags/VideoTagLoaderPlugin.cpp
index f3b97ee608..6e7e8e0fbc 100644
--- a/xbmc/video/tags/VideoTagLoaderPlugin.cpp
+++ b/xbmc/video/tags/VideoTagLoaderPlugin.cpp
@@ -9,6 +9,7 @@
#include "VideoTagLoaderPlugin.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/PluginDirectory.h"
diff --git a/xbmc/video/test/TestStacks.cpp b/xbmc/video/test/TestStacks.cpp
index f5d92eabf8..12639a1a5f 100644
--- a/xbmc/video/test/TestStacks.cpp
+++ b/xbmc/video/test/TestStacks.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "test/TestUtils.h"
diff --git a/xbmc/video/test/TestVideoFileItemClassify.cpp b/xbmc/video/test/TestVideoFileItemClassify.cpp
index 37b9b7e2e0..3fae8d23a0 100644
--- a/xbmc/video/test/TestVideoFileItemClassify.cpp
+++ b/xbmc/video/test/TestVideoFileItemClassify.cpp
@@ -196,6 +196,13 @@ TEST(TestVideoFileItemClassify, IsSubtitle)
EXPECT_FALSE(VIDEO::IsSubtitle(CFileItem("random.notasub", false)));
}
+TEST(TestVideoFileItemClassify, IsVideoAssetsFile)
+{
+ EXPECT_TRUE(VIDEO::IsVideoAssetFile(CFileItem("videodb://foo/bar?videoversionid=1", false)));
+ EXPECT_FALSE(VIDEO::IsVideoAssetFile(CFileItem("videodb://foo/bar?videoversionid=1", true)));
+ EXPECT_FALSE(VIDEO::IsVideoAssetFile(CFileItem("videodb://foo/bar", false)));
+}
+
TEST(TestVideoFileItemClassify, IsVideoDb)
{
EXPECT_TRUE(VIDEO::IsVideoDb(CFileItem("videodb://1/2/3", false)));
diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp
index bb7d08c8cd..9a8fb77ff6 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.cpp
+++ b/xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "ContextMenuManager.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
@@ -427,7 +428,7 @@ bool CGUIWindowVideoBase::ShowInfo(const CFileItemPtr& item2, const ScraperPtr&
if (bHasInfo)
{
// @todo add support to refresh movie version information
- if (!info || info->Content() == CONTENT_NONE || VIDEO::IsVideoAssetFile(*item))
+ if (!info || info->Content() == CONTENT_NONE || IsVideoAssetFile(*item))
item->SetProperty("xxuniqueid", "xx" + movieDetails.GetUniqueID()); // disable refresh button
item->SetProperty("CheckAutoPlayNextItem", IsActive());
*item->GetVideoInfoTag() = movieDetails;
@@ -835,6 +836,8 @@ void CGUIWindowVideoBase::GetContextButtons(int itemNumber, CContextButtons &but
}
if (item->IsSmartPlayList() || m_vecItems->IsSmartPlayList())
buttons.Add(CONTEXT_BUTTON_EDIT_SMART_PLAYLIST, 586);
+ if (IsBlurayPlaylist(*item))
+ buttons.Add(CONTEXT_BUTTON_CHOOSE_PLAYLIST, 13424);
}
}
CGUIMediaWindow::GetContextButtons(itemNumber, buttons);
@@ -891,6 +894,7 @@ bool CGUIWindowVideoBase::OnPlayStackPart(const std::shared_ptr<CFileItem>& item
bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
CFileItemPtr item;
+ m_forceSelection = false;
if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
item = m_vecItems->Get(itemNumber);
switch (button)
@@ -944,6 +948,11 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
return OnPlayAndQueueMedia(item);
case CONTEXT_BUTTON_PLAY_ONLY_THIS:
return OnPlayMedia(itemNumber);
+ case CONTEXT_BUTTON_CHOOSE_PLAYLIST:
+ {
+ m_forceSelection = true;
+ return OnPlayMedia(itemNumber);
+ }
default:
break;
}
@@ -981,7 +990,7 @@ bool CGUIWindowVideoBase::OnPlayMedia(const std::shared_ptr<CFileItem>& pItem,
if (m_thumbLoader.IsLoading())
m_thumbLoader.StopAsync();
- CServiceBroker::GetPlaylistPlayer().Play(itemCopy, player);
+ CServiceBroker::GetPlaylistPlayer().Play(itemCopy, player, m_forceSelection);
const auto& components = CServiceBroker::GetAppComponents();
const auto appPlayer = components.GetComponent<CApplicationPlayer>();
@@ -1117,6 +1126,8 @@ bool CGUIWindowVideoBase::PlayItem(const std::shared_ptr<CFileItem>& pItem,
return true;
}
+ m_forceSelection = false;
+
//! @todo get rid of "videos with versions as folder" hack!
if (pItem->m_bIsFolder && !pItem->IsPlugin() &&
!(pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->IsDefaultVideoVersion()))
diff --git a/xbmc/video/windows/GUIWindowVideoBase.h b/xbmc/video/windows/GUIWindowVideoBase.h
index 943db2bad4..acbd535cc1 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.h
+++ b/xbmc/video/windows/GUIWindowVideoBase.h
@@ -143,4 +143,6 @@ private:
\return true: the information of the item was modified. false: no change.
*/
bool ShowInfo(const CFileItemPtr& item, const ADDON::ScraperPtr& content);
+
+ bool m_forceSelection;
};
diff --git a/xbmc/video/windows/GUIWindowVideoNav.cpp b/xbmc/video/windows/GUIWindowVideoNav.cpp
index 9b96ec0121..69b81a760a 100644
--- a/xbmc/video/windows/GUIWindowVideoNav.cpp
+++ b/xbmc/video/windows/GUIWindowVideoNav.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowVideoNav.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PartyModeManager.h"
#include "ServiceBroker.h"
diff --git a/xbmc/video/windows/GUIWindowVideoPlaylist.cpp b/xbmc/video/windows/GUIWindowVideoPlaylist.cpp
index f806206e58..bb381a9dbc 100644
--- a/xbmc/video/windows/GUIWindowVideoPlaylist.cpp
+++ b/xbmc/video/windows/GUIWindowVideoPlaylist.cpp
@@ -8,6 +8,7 @@
#include "GUIWindowVideoPlaylist.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
diff --git a/xbmc/video/windows/VideoFileItemListModifier.cpp b/xbmc/video/windows/VideoFileItemListModifier.cpp
index 60c751e23b..2f5c222c62 100644
--- a/xbmc/video/windows/VideoFileItemListModifier.cpp
+++ b/xbmc/video/windows/VideoFileItemListModifier.cpp
@@ -9,6 +9,7 @@
#include "VideoFileItemListModifier.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/VideoDatabaseDirectory/DirectoryNode.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/view/GUIViewControl.cpp b/xbmc/view/GUIViewControl.cpp
index 3d4801b693..6ce4516b52 100644
--- a/xbmc/view/GUIViewControl.cpp
+++ b/xbmc/view/GUIViewControl.cpp
@@ -9,6 +9,7 @@
#include "GUIViewControl.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/view/GUIViewState.cpp b/xbmc/view/GUIViewState.cpp
index e0cf9d2aca..89c234a709 100644
--- a/xbmc/view/GUIViewState.cpp
+++ b/xbmc/view/GUIViewState.cpp
@@ -10,6 +10,7 @@
#include "AutoSwitch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp
index c95c873e10..4e6464e48e 100644
--- a/xbmc/windows/GUIMediaWindow.cpp
+++ b/xbmc/windows/GUIMediaWindow.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "FileItemListModification.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
@@ -60,6 +61,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoFileItemClassify.h"
+#include "video/VideoInfoTag.h"
#include "view/GUIViewState.h"
#include <inttypes.h>
@@ -1527,40 +1529,34 @@ bool CGUIMediaWindow::OnPlayAndQueueMedia(const CFileItemPtr& item, const std::s
PLAYLIST::Id playlistId = m_guiState->GetPlaylist();
if (playlistId != PLAYLIST::TYPE_NONE)
{
+ // Remove ZIP, RAR files and folders
+ CFileItemList playlist;
+ playlist.Copy(*m_vecItems, true);
+ playlist.erase(std::remove_if(playlist.begin(), playlist.end(),
+ [](const std::shared_ptr<CFileItem>& i)
+ { return i->IsZIP() || i->IsRAR() || i->m_bIsFolder; }),
+ playlist.end());
+
+ // Remove duplicates (eg. ISO/VIDEO_TS)
+ playlist.erase(
+ std::unique(playlist.begin(), playlist.end(),
+ [](const std::shared_ptr<CFileItem>& i, const std::shared_ptr<CFileItem>& j) {
+ return i->GetVideoInfoTag()->m_basePath == j->GetVideoInfoTag()->m_basePath;
+ }),
+ playlist.end());
+
+ // Chosen item
+ int mediaToPlay =
+ std::distance(playlist.begin(), std::find_if(playlist.begin(), playlist.end(),
+ [&item](const std::shared_ptr<CFileItem>& i) {
+ return i->GetVideoInfoTag()->m_basePath ==
+ item->GetVideoInfoTag()->m_basePath;
+ }));
+
+ // Add to playlist
CServiceBroker::GetPlaylistPlayer().ClearPlaylist(playlistId);
CServiceBroker::GetPlaylistPlayer().Reset();
- int mediaToPlay = 0;
-
- // first try to find mainDVD file (VIDEO_TS.IFO).
- // If we find this we should not allow to queue VOB files
- std::string mainDVD;
- for (int i = 0; i < m_vecItems->Size(); i++)
- {
- std::string path = URIUtils::GetFileName(m_vecItems->Get(i)->GetDynPath());
- if (StringUtils::EqualsNoCase(path, "VIDEO_TS.IFO"))
- {
- mainDVD = path;
- break;
- }
- }
-
- // now queue...
- for ( int i = 0; i < m_vecItems->Size(); i++ )
- {
- CFileItemPtr nItem = m_vecItems->Get(i);
-
- if (nItem->m_bIsFolder)
- continue;
-
- if (!nItem->IsZIP() && !nItem->IsRAR() &&
- (!IsDVDFile(*nItem) || (URIUtils::GetFileName(nItem->GetDynPath()) == mainDVD)))
- CServiceBroker::GetPlaylistPlayer().Add(playlistId, nItem);
-
- if (item->IsSamePath(nItem.get()))
- { // item that was clicked
- mediaToPlay = CServiceBroker::GetPlaylistPlayer().GetPlaylist(playlistId).size() - 1;
- }
- }
+ CServiceBroker::GetPlaylistPlayer().Add(playlistId, playlist);
// Save current window and directory to know where the selected item was
if (m_guiState)
diff --git a/xbmc/windows/GUIWindowLoginScreen.cpp b/xbmc/windows/GUIWindowLoginScreen.cpp
index 04eb5f9041..c95f6e4b61 100644
--- a/xbmc/windows/GUIWindowLoginScreen.cpp
+++ b/xbmc/windows/GUIWindowLoginScreen.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowLoginScreen.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "addons/Skin.h"