aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/scripts/android/Install.cmake1
-rw-r--r--system/shaders/GL/1.2/gl_shader_vert_clip.glsl39
-rw-r--r--system/shaders/GL/1.2/gl_shader_vert_simple.glsl26
-rw-r--r--system/shaders/GL/1.5/gl_shader_vert_clip.glsl39
-rw-r--r--system/shaders/GL/1.5/gl_shader_vert_simple.glsl26
-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.cpp1225
-rw-r--r--xbmc/FileItem.h188
-rw-r--r--xbmc/FileItemList.cpp1174
-rw-r--r--xbmc/FileItemList.h206
-rw-r--r--xbmc/NfoFile.cpp1
-rw-r--r--xbmc/PartyModeManager.cpp1
-rw-r--r--xbmc/PlayListPlayer.cpp3
-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.cpp6
-rw-r--r--xbmc/application/ApplicationPlayer.cpp4
-rw-r--r--xbmc/application/ApplicationPlayerCallback.cpp2
-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/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp16
-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.cpp10
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp5
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp8
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp4
-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/OverlayRendererGL.cpp5
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp5
-rw-r--r--xbmc/cores/paplayer/AudioDecoder.cpp2
-rw-r--r--xbmc/cores/playercorefactory/PlayerSelectionRule.cpp4
-rw-r--r--xbmc/dialogs/GUIDialogColorPicker.cpp1
-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.cpp6
-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.cpp6
-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.cpp9
-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/GUIControl.cpp22
-rw-r--r--xbmc/guilib/GUIControl.h5
-rw-r--r--xbmc/guilib/GUIFont.cpp16
-rw-r--r--xbmc/guilib/GUIFontManager.cpp1
-rw-r--r--xbmc/guilib/GUIFontTTF.cpp93
-rw-r--r--xbmc/guilib/GUIFontTTF.h12
-rw-r--r--xbmc/guilib/GUIFontTTFGL.cpp118
-rw-r--r--xbmc/guilib/GUIFontTTFGL.h4
-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/LibraryGUIInfo.cpp1
-rw-r--r--xbmc/guilib/guiinfo/SystemGUIInfo.cpp1
-rw-r--r--xbmc/guilib/guiinfo/VideoGUIInfo.cpp6
-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/ContextMenus.cpp8
-rw-r--r--xbmc/music/GUIViewStateMusic.cpp6
-rw-r--r--xbmc/music/MusicDatabase.cpp1
-rw-r--r--xbmc/music/MusicInfoLoader.cpp1
-rw-r--r--xbmc/music/MusicUtils.cpp3
-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.cpp5
-rw-r--r--xbmc/music/windows/GUIWindowMusicNav.cpp15
-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/UPnPInternal.cpp8
-rw-r--r--xbmc/network/upnp/UPnPPlayer.cpp4
-rw-r--r--xbmc/network/upnp/UPnPRenderer.cpp1
-rw-r--r--xbmc/network/upnp/UPnPServer.cpp11
-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/XBMCApp.cpp4
-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/gl/GLShader.cpp6
-rw-r--r--xbmc/rendering/gl/GLShader.h8
-rw-r--r--xbmc/rendering/gl/RenderSystemGL.cpp47
-rw-r--r--xbmc/rendering/gl/RenderSystemGL.h7
-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/ExecString.cpp5
-rw-r--r--xbmc/utils/FileOperationJob.h1
-rw-r--r--xbmc/utils/FontUtils.cpp1
-rw-r--r--xbmc/utils/Geometry.h5
-rw-r--r--xbmc/utils/GroupUtils.cpp1
-rw-r--r--xbmc/utils/RecentlyAddedJob.cpp1
-rw-r--r--xbmc/utils/SaveFileStateJob.cpp2
-rw-r--r--xbmc/utils/URIUtils.cpp10
-rw-r--r--xbmc/utils/test/TestVariant.cpp2
-rw-r--r--xbmc/video/ContextMenus.cpp17
-rw-r--r--xbmc/video/GUIViewStateVideo.cpp7
-rw-r--r--xbmc/video/VideoDatabase.cpp5
-rw-r--r--xbmc/video/VideoFileItemClassify.cpp82
-rw-r--r--xbmc/video/VideoFileItemClassify.h26
-rw-r--r--xbmc/video/VideoGeneratedImageFileLoader.cpp7
-rw-r--r--xbmc/video/VideoInfoScanner.cpp3
-rw-r--r--xbmc/video/VideoItemArtworkHandler.cpp1
-rw-r--r--xbmc/video/VideoThumbLoader.cpp7
-rw-r--r--xbmc/video/VideoUtils.cpp7
-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.cpp23
-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.cpp7
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.cpp1
-rw-r--r--xbmc/video/guilib/VideoVersionHelper.cpp17
-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.cpp127
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp48
-rw-r--r--xbmc/video/windows/GUIWindowVideoNav.cpp23
-rw-r--r--xbmc/video/windows/GUIWindowVideoPlaylist.cpp5
-rw-r--r--xbmc/video/windows/VideoFileItemListModifier.cpp7
-rw-r--r--xbmc/view/GUIViewControl.cpp1
-rw-r--r--xbmc/view/GUIViewState.cpp1
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.h11
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.mm21
-rw-r--r--xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm34
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.h1
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.mm12
-rw-r--r--xbmc/windowing/win10/WinSystemWin10.cpp9
-rw-r--r--xbmc/windowing/win10/WinSystemWin10.h4
-rw-r--r--xbmc/windowing/win10/WinSystemWin10DX.cpp17
-rw-r--r--xbmc/windows/GUIMediaWindow.cpp6
-rw-r--r--xbmc/windows/GUIWindowLoginScreen.cpp1
316 files changed, 2949 insertions, 1844 deletions
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/GL/1.2/gl_shader_vert_clip.glsl b/system/shaders/GL/1.2/gl_shader_vert_clip.glsl
new file mode 100644
index 0000000000..37d67946f5
--- /dev/null
+++ b/system/shaders/GL/1.2/gl_shader_vert_clip.glsl
@@ -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 120
+
+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/GL/1.2/gl_shader_vert_simple.glsl b/system/shaders/GL/1.2/gl_shader_vert_simple.glsl
new file mode 100644
index 0000000000..f06893a085
--- /dev/null
+++ b/system/shaders/GL/1.2/gl_shader_vert_simple.glsl
@@ -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 120
+
+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/system/shaders/GL/1.5/gl_shader_vert_clip.glsl b/system/shaders/GL/1.5/gl_shader_vert_clip.glsl
new file mode 100644
index 0000000000..2fa1c63da1
--- /dev/null
+++ b/system/shaders/GL/1.5/gl_shader_vert_clip.glsl
@@ -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 150
+
+in vec4 m_attrpos;
+in vec4 m_attrcol;
+in vec4 m_attrcord0;
+in vec4 m_attrcord1;
+out vec4 m_cord0;
+out vec4 m_cord1;
+out 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/GL/1.5/gl_shader_vert_simple.glsl b/system/shaders/GL/1.5/gl_shader_vert_simple.glsl
new file mode 100644
index 0000000000..9c1552d7a4
--- /dev/null
+++ b/system/shaders/GL/1.5/gl_shader_vert_simple.glsl
@@ -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 150
+
+in vec4 m_attrpos;
+in vec4 m_attrcol;
+in vec4 m_attrcord0;
+in vec4 m_attrcord1;
+out vec4 m_cord0;
+out vec4 m_cord1;
+out 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/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 2176c3e8e5..558a5a2ad8 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;
@@ -853,7 +850,7 @@ bool CFileItem::Exists(bool bUseCache /* = true */) const
|| IsPVR())
return true;
- if (IsVideoDb() && HasVideoInfoTag())
+ if (IsVideoDb(*this) && HasVideoInfoTag())
{
CFileItem dbItem(m_bIsFolder ? GetVideoInfoTag()->m_strPath : GetVideoInfoTag()->m_strFileNameAndPath, m_bIsFolder);
return dbItem.Exists();
@@ -915,17 +912,6 @@ bool CFileItem::IsPVRTimer() const
return HasPVRTimerInfoTag();
}
-bool CFileItem::IsDiscStub() const
-{
- if (IsVideoDb() && HasVideoInfoTag())
- {
- CFileItem dbItem(m_bIsFolder ? GetVideoInfoTag()->m_strPath : GetVideoInfoTag()->m_strFileNameAndPath, m_bIsFolder);
- return dbItem.IsDiscStub();
- }
-
- return URIUtils::HasExtension(m_strPath, CServiceBroker::GetFileExtensionProvider().GetDiscStubExtensions());
-}
-
bool CFileItem::IsAudio() const
{
/* check preset mime type */
@@ -1030,11 +1016,6 @@ bool CFileItem::IsLyrics() const
return URIUtils::HasExtension(m_strPath, ".cdg|.lrc");
}
-bool CFileItem::IsSubtitle() const
-{
- return URIUtils::HasExtension(m_strPath, CServiceBroker::GetFileExtensionProvider().GetSubtitleExtensions());
-}
-
bool CFileItem::IsCUESheet() const
{
return URIUtils::HasExtension(m_strPath, ".cue");
@@ -1142,12 +1123,6 @@ bool CFileItem::IsNFO() const
return URIUtils::HasExtension(m_strPath, ".nfo");
}
-bool CFileItem::IsVideoExtras() const
-{
- return m_bIsFolder &&
- StringUtils::EqualsNoCase(URIUtils::GetFileOrFolderName(m_strPath), "extras");
-}
-
bool CFileItem::IsDiscImage() const
{
return URIUtils::IsDiscImage(GetDynPath());
@@ -1155,38 +1130,10 @@ bool CFileItem::IsDiscImage() const
bool CFileItem::IsOpticalMediaFile() const
{
- if (IsDVDFile(false, true))
+ if (IsDVDFile(*this, false, true))
return true;
- return IsBDFile();
-}
-
-bool CFileItem::IsDVDFile(bool bVobs /*= true*/, bool bIfos /*= true*/) const
-{
- std::string strFileName = URIUtils::GetFileName(GetDynPath());
- if (bIfos)
- {
- if (StringUtils::EqualsNoCase(strFileName, "video_ts.ifo"))
- return true;
- if (StringUtils::StartsWithNoCase(strFileName, "vts_") && StringUtils::EndsWithNoCase(strFileName, "_0.ifo") && strFileName.length() == 12)
- return true;
- }
- if (bVobs)
- {
- if (StringUtils::EqualsNoCase(strFileName, "video_ts.vob"))
- return true;
- if (StringUtils::StartsWithNoCase(strFileName, "vts_") && StringUtils::EndsWithNoCase(strFileName, ".vob"))
- return true;
- }
-
- return false;
-}
-
-bool CFileItem::IsBDFile() const
-{
- std::string strFileName = URIUtils::GetFileName(GetDynPath());
- return (StringUtils::EqualsNoCase(strFileName, "index.bdmv") || StringUtils::EqualsNoCase(strFileName, "MovieObject.bdmv")
- || StringUtils::EqualsNoCase(strFileName, "INDEX.BDM") || StringUtils::EqualsNoCase(strFileName, "MOVIEOBJ.BDM"));
+ return IsBDFile(*this);
}
bool CFileItem::IsRAR() const
@@ -1268,17 +1215,7 @@ bool CFileItem::IsBluray() const
CFileItem item = CFileItem(VIDEO_UTILS::GetOpticalMediaPath(*this), false);
- return item.IsBDFile();
-}
-
-bool CFileItem::IsProtectedBlurayDisc() const
-{
- std::string path;
- path = URIUtils::AddFileToFolder(GetPath(), "AACS", "Unit_Key_RO.inf");
- if (CFile::Exists(path))
- return true;
-
- return false;
+ return IsBDFile(item);
}
bool CFileItem::IsCDDA() const
@@ -1346,11 +1283,6 @@ bool CFileItem::IsMusicDb() const
return URIUtils::IsMusicDb(m_strPath);
}
-bool CFileItem::IsVideoDb() const
-{
- return URIUtils::IsVideoDb(m_strPath);
-}
-
bool CFileItem::IsVirtualDirectoryRoot() const
{
return (m_bIsFolder && m_strPath.empty());
@@ -1658,7 +1590,7 @@ bool CFileItem::IsSamePath(const CFileItem *item) const
dbItem.SetProperty("item_start", GetProperty("item_start"));
return dbItem.IsSamePath(item);
}
- if (IsVideoDb() && HasVideoInfoTag())
+ if (IsVideoDb(*this) && HasVideoInfoTag())
{
CFileItem dbItem(GetVideoInfoTag()->m_strFileNameAndPath, false);
if (HasProperty("item_start"))
@@ -1672,7 +1604,7 @@ bool CFileItem::IsSamePath(const CFileItem *item) const
dbItem.SetProperty("item_start", item->GetProperty("item_start"));
return IsSamePath(&dbItem);
}
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (IsVideoDb(*item) && item->HasVideoInfoTag())
{
CFileItem dbItem(item->GetVideoInfoTag()->m_strFileNameAndPath, false);
if (item->HasProperty("item_start"))
@@ -2122,1083 +2054,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())
- 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())
- 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()
@@ -3532,7 +2387,7 @@ std::string CFileItem::GetBaseMoviePath(bool bUseFolderNames) const
std::string CFileItem::GetLocalFanart() const
{
- if (IsVideoDb())
+ if (IsVideoDb(*this))
{
if (!HasVideoInfoTag())
return ""; // nothing can be done
@@ -3706,7 +2561,7 @@ bool CFileItem::LoadGameTag()
bool CFileItem::LoadDetails()
{
- if (IsVideoDb())
+ if (IsVideoDb(*this))
{
if (HasVideoInfoTag())
return true;
@@ -3886,66 +2741,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 972601c317..473c11c9d7 100644
--- a/xbmc/FileItem.h
+++ b/xbmc/FileItem.h
@@ -156,8 +156,6 @@ public:
bool Exists(bool bUseCache = true) const;
- bool IsDiscStub() const;
-
/*!
\brief Check whether an item is a picture item. Note that this returns true for
anything with a picture info tag, so that may include eg. folders.
@@ -165,7 +163,6 @@ public:
*/
bool IsPicture() const;
bool IsLyrics() const;
- bool IsSubtitle() const;
/*!
\brief Check whether an item is an audio item. Note that this returns true for
@@ -199,13 +196,9 @@ public:
bool IsAddonsPath() const;
bool IsSourcesPath() const;
bool IsNFO() const;
- bool IsVideoExtras() const;
bool IsDiscImage() const;
bool IsOpticalMediaFile() const;
- bool IsDVDFile(bool bVobs = true, bool bIfos = true) const;
- bool IsBDFile() const;
bool IsBluray() const;
- bool IsProtectedBlurayDisc() const;
bool IsRAR() const;
bool IsAPK() const;
bool IsZIP() const;
@@ -225,7 +218,6 @@ public:
bool IsFavourite() const;
bool IsMultiPath() const;
bool IsMusicDb() const;
- bool IsVideoDb() const;
bool IsEPG() const;
bool IsPVRChannel() const;
bool IsPVRChannelGroup() const;
@@ -618,6 +610,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()
@@ -701,181 +694,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/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 96cdccb609..feaa7f4fb4 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"
@@ -333,7 +334,7 @@ bool CPlayListPlayer::Play(int iSong,
m_iCurrentSong = iSong;
CFileItemPtr item = playlist[m_iCurrentSong];
- if (item->IsVideoDb() && !item->HasVideoInfoTag())
+ if (IsVideoDb(*item) && !item->HasVideoInfoTag())
*(item->GetVideoInfoTag()) = XFILE::CVideoDatabaseFile::GetVideoTag(CURL(item->GetDynPath()));
playlist.SetPlayed(true);
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 4dcb893702..6541a22759 100644
--- a/xbmc/application/Application.cpp
+++ b/xbmc/application/Application.cpp
@@ -2307,7 +2307,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
CUtil::ClearSubtitles();
}
- if (item.IsDiscStub())
+ if (IsDiscStub(item))
{
return CServiceBroker::GetMediaManager().playStubFile(item);
}
@@ -2356,7 +2356,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
std::string path = item.GetPath();
std::string videoInfoTagPath(item.GetVideoInfoTag()->m_strFileNameAndPath);
- if (videoInfoTagPath.find("removable://") == 0 || item.IsVideoDb())
+ if (videoInfoTagPath.find("removable://") == 0 || IsVideoDb(item))
path = videoInfoTagPath;
// Note that we need to load the tag from database also if the item already has a tag,
@@ -2426,7 +2426,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) &&
- (item.IsBDFile() || item.IsDiscImage()))
+ (IsBDFile(item) || item.IsDiscImage()))
{
// No video selection when using external or remote players (they handle it if supported)
const bool isSimpleMenuAllowed = [&]()
diff --git a/xbmc/application/ApplicationPlayer.cpp b/xbmc/application/ApplicationPlayer.cpp
index b517c78fd0..d088f46b6a 100644
--- a/xbmc/application/ApplicationPlayer.cpp
+++ b/xbmc/application/ApplicationPlayer.cpp
@@ -17,9 +17,11 @@
#include "guilib/GUIWindowManager.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
+#include "video/VideoFileItemClassify.h"
#include <mutex>
+using namespace KODI;
using namespace std::chrono_literals;
std::shared_ptr<const IPlayer> CApplicationPlayer::GetInternal() const
@@ -99,7 +101,7 @@ bool CApplicationPlayer::OpenFile(const CFileItem& item, const CPlayerOptions& o
{
bool needToClose = false;
- if (item.IsDiscImage() || item.IsDVDFile())
+ if (item.IsDiscImage() || VIDEO::IsDVDFile(item))
needToClose = true;
if (player->m_name != newPlayer)
diff --git a/xbmc/application/ApplicationPlayerCallback.cpp b/xbmc/application/ApplicationPlayerCallback.cpp
index 2ff6353952..637f67ddcc 100644
--- a/xbmc/application/ApplicationPlayerCallback.cpp
+++ b/xbmc/application/ApplicationPlayerCallback.cpp
@@ -57,7 +57,7 @@ void CApplicationPlayerCallback::OnPlayBackStarted(const CFileItem& file)
std::shared_ptr<CFileItem> itemCurrentFile;
// check if VideoPlayer should set file item stream details from its current streams
- const bool isBlu_dvd_image_or_stream = (URIUtils::IsBluray(file.GetPath()) || file.IsDVDFile() ||
+ const bool isBlu_dvd_image_or_stream = (URIUtils::IsBluray(file.GetPath()) || IsDVDFile(file) ||
file.IsDiscImage() || file.IsInternetStream());
const bool hasNoStreamDetails =
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/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
index 02c8eb1b83..e897cbd3ea 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
@@ -148,21 +148,21 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi
AVChannel outChan = av_channel_layout_channel_from_index(&dstChLayout, out);
switch (outChan)
{
- case AV_CH_FRONT_LEFT:
- case AV_CH_BACK_LEFT:
- case AV_CH_SIDE_LEFT:
+ case AV_CHAN_FRONT_LEFT:
+ case AV_CHAN_BACK_LEFT:
+ case AV_CHAN_SIDE_LEFT:
m_rematrix[out][0] = 1.0;
break;
- case AV_CH_FRONT_RIGHT:
- case AV_CH_BACK_RIGHT:
- case AV_CH_SIDE_RIGHT:
+ case AV_CHAN_FRONT_RIGHT:
+ case AV_CHAN_BACK_RIGHT:
+ case AV_CHAN_SIDE_RIGHT:
m_rematrix[out][1] = 1.0;
break;
- case AV_CH_FRONT_CENTER:
+ case AV_CHAN_FRONT_CENTER:
m_rematrix[out][0] = 0.5;
m_rematrix[out][1] = 0.5;
break;
- case AV_CH_LOW_FREQUENCY:
+ case AV_CHAN_LOW_FREQUENCY:
m_rematrix[out][0] = 0.5;
m_rematrix[out][1] = 0.5;
break;
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 bd89cb4629..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"
@@ -20,6 +21,7 @@
#include "utils/MemUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#ifdef HAVE_LIBBLURAY
#include "DVDInputStreams/DVDInputStreamBluray.h"
@@ -49,6 +51,8 @@ extern "C" {
#include <libswscale/swscale.h>
}
+using namespace KODI;
+
bool CDVDFileInfo::GetFileDuration(const std::string &path, int& duration)
{
std::unique_ptr<CDVDDemux> demux;
@@ -258,12 +262,12 @@ bool CDVDFileInfo::CanExtract(const CFileItem& fileItem)
URIUtils::IsPVRRecording(fileItem.GetDynPath()) ||
// plugin path not fully resolved
URIUtils::IsPlugin(fileItem.GetDynPath()) || URIUtils::IsUPnP(fileItem.GetPath()) ||
- fileItem.IsInternetStream() || fileItem.IsDiscStub() || fileItem.IsPlayList())
+ fileItem.IsInternetStream() || VIDEO::IsDiscStub(fileItem) || fileItem.IsPlayList())
return false;
// mostly can't extract from discs and files from discs.
- if (URIUtils::IsBluray(fileItem.GetPath()) || fileItem.IsBDFile() || fileItem.IsDVD() ||
- fileItem.IsDiscImage() || fileItem.IsDVDFile(false, true))
+ if (URIUtils::IsBluray(fileItem.GetPath()) || VIDEO::IsBDFile(fileItem) || fileItem.IsDVD() ||
+ fileItem.IsDiscImage() || VIDEO::IsDVDFile(fileItem, false, true))
return false;
// For HTTP/FTP we only allow extraction when on a LAN
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp
index e25e35dcaf..2b65938437 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp
@@ -32,9 +32,12 @@
#include "storage/MediaManager.h"
#include "utils/FileUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
#include <memory>
+using namespace KODI;
+
std::shared_ptr<CDVDInputStream> CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio)
{
using namespace ADDON;
@@ -101,7 +104,7 @@ std::shared_ptr<CDVDInputStream> CDVDFactoryInputStream::CreateInputStream(IVide
}
#endif
- if (fileitem.IsDVDFile(false, true))
+ if (VIDEO::IsDVDFile(fileitem, false, true))
return std::make_shared<CDVDInputStreamNavigator>(pPlayer, fileitem);
else if (URIUtils::IsPVRChannel(file))
return std::make_shared<CInputStreamPVRChannel>(pPlayer, fileitem);
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
index a87888c7be..8936399b94 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
@@ -27,6 +27,7 @@
#include "utils/URIUtils.h"
#include "utils/XTimeUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include <functional>
#include <limits>
@@ -37,6 +38,7 @@
#define LIBBLURAY_BYTESEEK 0
+using namespace KODI;
using namespace XFILE;
using namespace std::chrono_literals;
@@ -152,7 +154,7 @@ bool CDVDInputStreamBluray::Open()
// Check whether disc is AACS protected
CURL url3(root);
CFileItem base(url3, false);
- openDisc = base.IsProtectedBlurayDisc();
+ openDisc = VIDEO::IsProtectedBlurayDisc(base);
// check for a menu call for an image file
if (StringUtils::EqualsNoCase(filename, "menu"))
@@ -166,7 +168,7 @@ bool CDVDInputStreamBluray::Open()
// Check whether disc is AACS protected
if (!openDisc)
- openDisc = item.IsProtectedBlurayDisc();
+ openDisc = VIDEO::IsProtectedBlurayDisc(item);
if (item.IsDiscImage())
{
@@ -184,7 +186,7 @@ bool CDVDInputStreamBluray::Open()
openStream = true;
}
- else if (m_item.IsProtectedBlurayDisc())
+ else if (VIDEO::IsProtectedBlurayDisc(m_item))
{
openDisc = true;
}
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
index 4214673f08..9ebd8d2c53 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
@@ -12,7 +12,9 @@
#include "filesystem/IFile.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
+using namespace KODI;
using namespace XFILE;
CDVDInputStreamFile::CDVDInputStreamFile(const CFileItem& fileitem, unsigned int flags)
@@ -44,7 +46,7 @@ bool CDVDInputStreamFile::Open()
unsigned int flags = m_flags;
// If this file is audio and/or video (= not a subtitle) flag to caller
- if (!m_item.IsSubtitle())
+ if (!VIDEO::IsSubtitle(m_item))
flags |= READ_AUDIO_VIDEO;
std::string content = m_item.GetMimeType();
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/OverlayRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp
index 3caa28e4bf..8559d22eae 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp
@@ -293,6 +293,11 @@ void COverlayGlyphGL::Render(SRenderState& state)
GLint posLoc = renderSystem->ShaderGetPos();
GLint colLoc = renderSystem->ShaderGetCol();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
+ GLint matrixUniformLoc = renderSystem->ShaderGetMatrix();
+
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
std::vector<VERTEX> vecVertices(6 * m_vertex.size() / 4);
VERTEX* vertices = vecVertices.data();
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/cores/paplayer/AudioDecoder.cpp b/xbmc/cores/paplayer/AudioDecoder.cpp
index 03dc907c0b..a960776287 100644
--- a/xbmc/cores/paplayer/AudioDecoder.cpp
+++ b/xbmc/cores/paplayer/AudioDecoder.cpp
@@ -75,7 +75,7 @@ bool CAudioDecoder::Create(const CFileItem &file, int64_t seekOffset)
filecache = settings->GetInt(CSettings::SETTING_CACHE_HARDDISK);
else if ( file.IsOnDVD() )
filecache = settings->GetInt(CSettings::SETTING_CACHEAUDIO_DVDROM);
- else if ( file.IsOnLAN() )
+ else if (file.IsOnLAN())
filecache = settings->GetInt(CSettings::SETTING_CACHEAUDIO_LAN);
// create our codec
diff --git a/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp b/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
index 4d4f390b5b..d8441dd0c6 100644
--- a/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
+++ b/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
@@ -128,11 +128,11 @@ void CPlayerSelectionRule::GetPlayers(const CFileItem& item, std::vector<std::st
if (m_tRemote >= 0 && (m_tRemote > 0) != item.IsRemote())
return;
- if (m_tBD >= 0 && (m_tBD > 0) != (item.IsBDFile() && item.IsOnDVD()))
+ if (m_tBD >= 0 && (m_tBD > 0) != (VIDEO::IsBDFile(item) && item.IsOnDVD()))
return;
if (m_tDVD >= 0 && (m_tDVD > 0) != item.IsDVD())
return;
- if (m_tDVDFile >= 0 && (m_tDVDFile > 0) != item.IsDVDFile())
+ if (m_tDVDFile >= 0 && (m_tDVDFile > 0) != VIDEO::IsDVDFile(item))
return;
if (m_tDiscImage >= 0 && (m_tDiscImage > 0) != item.IsDiscImage())
return;
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/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 0d4d11a830..61016f477a 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"
@@ -25,8 +26,11 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
+using namespace KODI;
+
namespace
{
class CGetDirectoryItems : public IRunnable
@@ -54,7 +58,7 @@ bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item)
if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_DISC_PLAYBACK) != BD_PLAYBACK_SIMPLE_MENU)
return true;
- if (item.IsBDFile())
+ if (VIDEO::IsBDFile(item))
{
std::string root = URIUtils::GetParentPath(item.GetDynPath());
URIUtils::RemoveSlashAtEnd(root);
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 fbcdb4d0d4..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"
@@ -25,7 +26,9 @@
#include "utils/JobManager.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
+using namespace KODI;
using namespace XFILE;
using namespace std::chrono_literals;
@@ -282,7 +285,8 @@ bool CDirectory::GetDirectory(const CURL& url,
// Should any of the files we read be treated as a directory?
// Disable for database folders, as they already contain the extracted items
- if (!(hints.flags & DIR_FLAG_NO_FILE_DIRS) && !items.IsMusicDb() && !items.IsVideoDb() && !items.IsSmartPlayList())
+ if (!(hints.flags & DIR_FLAG_NO_FILE_DIRS) && !items.IsMusicDb() && !VIDEO::IsVideoDb(items) &&
+ !items.IsSmartPlayList())
FilterFileDirectories(items, hints.mask);
// Correct items for path substitution
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 b83ee2ed49..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"
@@ -19,7 +20,9 @@
#include "storage/MediaManager.h"
#include "utils/FileUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
+using namespace KODI;
using namespace XFILE;
CSourcesDirectory::CSourcesDirectory(void) = default;
@@ -68,10 +71,8 @@ bool CSourcesDirectory::GetDirectory(const VECSOURCES &sources, CFileItemList &i
else if ( pItem->IsPath("special://musicplaylists/")
|| pItem->IsPath("special://videoplaylists/"))
strIcon = "DefaultPlaylist.png";
- else if ( pItem->IsVideoDb()
- || pItem->IsMusicDb()
- || pItem->IsPlugin()
- || pItem->IsPath("musicsearch://"))
+ else if (VIDEO::IsVideoDb(*pItem) || pItem->IsMusicDb() || pItem->IsPlugin() ||
+ pItem->IsPath("musicsearch://"))
strIcon = "DefaultFolder.png";
else if (pItem->IsRemote())
strIcon = "DefaultNetwork.png";
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/GUIControl.cpp b/xbmc/guilib/GUIControl.cpp
index 689c55f257..0c6a902ebb 100644
--- a/xbmc/guilib/GUIControl.cpp
+++ b/xbmc/guilib/GUIControl.cpp
@@ -180,6 +180,10 @@ void CGUIControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregio
// 3. reset the animation transform
void CGUIControl::DoRender()
{
+ if (IsControlRenderable() &&
+ !m_renderRegion.Intersects(CServiceBroker::GetWinSystem()->GetGfxContext().GetScissors()))
+ return;
+
if (IsVisible() && !m_isCulled)
{
bool hasStereo =
@@ -954,6 +958,24 @@ void CGUIControl::UpdateControlStats()
}
}
+bool CGUIControl::IsControlRenderable()
+{
+ switch (ControlType)
+ {
+ case GUICONTAINER_EPGGRID:
+ case GUICONTAINER_FIXEDLIST:
+ case GUICONTAINER_LIST:
+ case GUICONTAINER_PANEL:
+ case GUICONTAINER_WRAPLIST:
+ case GUICONTROL_GROUP:
+ case GUICONTROL_GROUPLIST:
+ case GUICONTROL_LISTGROUP:
+ return false;
+ default:
+ return true;
+ }
+}
+
void CGUIControl::SetHitRect(const CRect& rect, const UTILS::COLOR::Color& color)
{
m_hitRect = rect;
diff --git a/xbmc/guilib/GUIControl.h b/xbmc/guilib/GUIControl.h
index 4cedee0761..a57f02243b 100644
--- a/xbmc/guilib/GUIControl.h
+++ b/xbmc/guilib/GUIControl.h
@@ -306,6 +306,11 @@ public:
};
GUICONTROLTYPES GetControlType() const { return ControlType; }
+ /*! \brief Test whether the control is "drawable" (not a group or similar)
+ \return true if the control has textures/labels it wants to render
+ */
+ bool IsControlRenderable();
+
enum GUIVISIBLE { HIDDEN = 0, DELAYED, VISIBLE };
enum GUISCROLLVALUE { FOCUS = 0, NEVER, ALWAYS };
diff --git a/xbmc/guilib/GUIFont.cpp b/xbmc/guilib/GUIFont.cpp
index 784dd75971..bf0c014a0a 100644
--- a/xbmc/guilib/GUIFont.cpp
+++ b/xbmc/guilib/GUIFont.cpp
@@ -234,18 +234,18 @@ void CGUIFont::DrawScrollingText(float x,
shadowColors.emplace_back((renderColor & 0xff000000) != 0 ? shadowColor : 0);
for (float dx = -offset; dx < maxWidth; dx += scrollInfo.m_totalWidth)
{
- m_font->DrawTextInternal(context, x + dx + 1, y + 1, shadowColors, text, alignment,
- textPixelWidth, scroll);
- m_font->DrawTextInternal(context, x + dx + scrollInfo.m_textWidth + 1, y + 1, shadowColors,
- scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll);
+ m_font->DrawTextInternal(context, x + 1, y + 1, shadowColors, text, alignment, textPixelWidth,
+ scroll, dx);
+ m_font->DrawTextInternal(context, x + scrollInfo.m_textWidth + 1, y + 1, shadowColors,
+ scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll, dx);
}
}
for (float dx = -offset; dx < maxWidth; dx += scrollInfo.m_totalWidth)
{
- m_font->DrawTextInternal(context, x + dx, y, renderColors, text, alignment, textPixelWidth,
- scroll);
- m_font->DrawTextInternal(context, x + dx + scrollInfo.m_textWidth, y, renderColors,
- scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll);
+ m_font->DrawTextInternal(context, x, y, renderColors, text, alignment, textPixelWidth, scroll,
+ dx);
+ m_font->DrawTextInternal(context, x + scrollInfo.m_textWidth, y, renderColors,
+ scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll, dx);
}
context.RestoreClipRegion();
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 50d0e07a44..ff11db14f8 100644
--- a/xbmc/guilib/GUIFontTTF.cpp
+++ b/xbmc/guilib/GUIFontTTF.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -369,7 +369,9 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
const vecText& text,
uint32_t alignment,
float maxPixelWidth,
- bool scrolling)
+ bool scrolling,
+ float dx,
+ float dy)
{
if (text.empty())
{
@@ -379,15 +381,40 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
Begin();
uint32_t rawAlignment = alignment;
bool dirtyCache(false);
+
+#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);
+ y = std::round(y);
+#else
+ x += dx;
+ y += dy;
+#endif
+
+#if not defined(HAS_DX)
+ // GL can scissor and shader clip
+ const bool hardwareClipping = true;
+#else
+ // FIXME: remove static (CPU based) clipping for GLES/DX
const bool hardwareClipping = m_renderSystem->ScissorsCanEffectClipping();
+#endif
+
+ // FIXME: remove positional stuff once GLES/DX are brought up to date
CGUIFontCacheStaticPosition staticPos(x, y);
CGUIFontCacheDynamicPosition dynamicPos;
+
+#if not defined(HAS_DX)
+ // dummy positions for the time being
+ dynamicPos = CGUIFontCacheDynamicPosition(0.0f, 0.0f, 0.0f);
+#else
if (hardwareClipping)
{
dynamicPos =
CGUIFontCacheDynamicPosition(context.ScaleFinalXCoord(x, y), context.ScaleFinalYCoord(x, y),
context.ScaleFinalZCoord(x, y));
}
+#endif
CVertexBuffer unusedVertexBuffer;
CVertexBuffer& vertexBuffer =
@@ -425,8 +452,14 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
const std::vector<Glyph> glyphs = GetHarfBuzzShapedGlyphs(text);
// save the origin, which is scaled separately
+#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;
+#else
m_originX = x;
m_originY = y;
+#endif
// cache the ellipses width
if (!m_ellipseCached)
@@ -677,7 +710,11 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
scrolling, std::chrono::steady_clock::now(), dirtyCache);
CVertexBuffer newVertexBuffer = CreateVertexBuffer(*tempVertices);
vertexBuffer = newVertexBuffer;
+#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());
+#endif
}
else
{
@@ -691,8 +728,12 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
else
{
if (hardwareClipping)
+#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,
context.GetClipRegion());
+#endif
else
/* Append the vertices from the cache to the set collected since the first Begin() call */
m_vertex.insert(m_vertex.end(), vertices->begin(), vertices->end());
@@ -1098,12 +1139,19 @@ 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 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
CRect vertex((posX + ch->m_offsetX) * context.GetGUIScaleX(),
(posY + ch->m_offsetY) * context.GetGUIScaleY(),
(posX + ch->m_offsetX + width) * context.GetGUIScaleX(),
(posY + ch->m_offsetY + height) * context.GetGUIScaleY());
vertex += CPoint(m_originX, m_originY);
+#endif
CRect texture(ch->m_left, ch->m_top, ch->m_right, ch->m_bottom);
+
+#if defined(HAS_DX)
if (!m_renderSystem->ScissorsCanEffectClipping())
context.ClipRect(vertex, texture);
@@ -1163,6 +1211,14 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
const float tr = texture.x2 * m_textureScaleX;
const float tt = texture.y1 * m_textureScaleY;
const float tb = texture.y2 * m_textureScaleY;
+#else
+ // when scaling by shader, we have to grow the vertex and texture coords
+ // by .5 or we would ommit pixels when animating.
+ const float tl = (texture.x1 - .5f) * m_textureScaleX;
+ const float tr = (texture.x2 + .5f) * m_textureScaleX;
+ const float tt = (texture.y1 - .5f) * m_textureScaleY;
+ const float tb = (texture.y2 + .5f) * m_textureScaleY;
+#endif
vertices.resize(vertices.size() + VERTEX_PER_GLYPH);
SVertex* v = &vertices[vertices.size() - VERTEX_PER_GLYPH];
@@ -1208,29 +1264,38 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
v[3].v = tb;
#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.
+
+ // nudge position to align with raster grid. messes up kerning, but also avoids
+ // linear filtering (when not scaled/rotated).
+ float xOffset = 0.0f;
+ if (roundX)
+ xOffset = (vertex.x1 - std::floor(vertex.x1));
+ float yOffset = (vertex.y1 - std::floor(vertex.y1));
+
v[0].u = tl;
v[0].v = tt;
- v[0].x = x[0];
- v[0].y = y[0];
- v[0].z = z[0];
+ v[0].x = vertex.x1 - xOffset - 0.5f;
+ v[0].y = vertex.y1 - yOffset - 0.5f;
+ v[0].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[1].x = vertex.x1 - xOffset - 0.5f;
+ v[1].y = vertex.y2 - yOffset + 0.5f;
+ v[1].z = 0;
v[2].u = tr;
v[2].v = tt;
- v[2].x = x[1];
- v[2].y = y[1];
- v[2].z = z[1];
+ v[2].x = vertex.x2 - xOffset + 0.5f;
+ v[2].y = vertex.y1 - yOffset - 0.5f;
+ v[2].z = 0;
v[3].u = tr;
v[3].v = tb;
- v[3].x = x[2];
- v[3].y = y[2];
- v[3].z = z[2];
+ v[3].x = vertex.x2 - xOffset + 0.5f;
+ v[3].y = vertex.y2 - yOffset + 0.5f;
+ v[3].z = 0;
#endif
}
diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
index 2ed270343d..02a0ac16df 100644
--- a/xbmc/guilib/GUIFontTTF.h
+++ b/xbmc/guilib/GUIFontTTF.h
@@ -164,7 +164,9 @@ protected:
const vecText& text,
uint32_t alignment,
float maxPixelWidth,
- bool scrolling);
+ bool scrolling,
+ float dx = 0.0f,
+ float dy = 0.0f);
float m_height{0.0f};
@@ -238,16 +240,22 @@ protected:
float m_translateX;
float m_translateY;
float m_translateZ;
+ float m_offsetX; // skews the "raw" mesh before applying UI matrix (useful for scrolling)
+ float m_offsetY;
const CVertexBuffer* m_vertexBuffer;
CRect m_clip;
CTranslatedVertices(float translateX,
float translateY,
float translateZ,
const CVertexBuffer* vertexBuffer,
- const CRect& clip)
+ const CRect& clip,
+ float offsetX = 0.0f,
+ float offsetY = 0.0f)
: m_translateX(translateX),
m_translateY(translateY),
m_translateZ(translateZ),
+ m_offsetX(offsetX),
+ m_offsetY(offsetY),
m_vertexBuffer(vertexBuffer),
m_clip(clip)
{
diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
index 529078811e..3706883911 100644
--- a/xbmc/guilib/GUIFontTTFGL.cpp
+++ b/xbmc/guilib/GUIFontTTFGL.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -65,7 +65,18 @@ bool CGUIFontTTFGL::FirstBegin()
internalFormat = GL_R8;
else
internalFormat = GL_LUMINANCE;
+
renderSystem->EnableShader(ShaderMethodGL::SM_FONTS);
+ if (renderSystem->ScissorsCanEffectClipping())
+ {
+ m_scissorClip = true;
+ }
+ else
+ {
+ m_scissorClip = false;
+ renderSystem->ResetScissors();
+ renderSystem->EnableShader(ShaderMethodGL::SM_FONTS_SHADER_CLIP);
+ }
if (m_textureStatus == TEXTURE_REALLOCATED)
{
@@ -129,6 +140,9 @@ bool CGUIFontTTFGL::FirstBegin()
void CGUIFontTTFGL::LastEnd()
{
+ // static vertex arrays are not supported anymore
+ assert(m_vertex.empty());
+
CWinSystemBase* const winSystem = CServiceBroker::GetWinSystem();
if (!winSystem)
return;
@@ -138,7 +152,9 @@ void CGUIFontTTFGL::LastEnd()
GLint posLoc = renderSystem->ShaderGetPos();
GLint colLoc = renderSystem->ShaderGetCol();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
- GLint modelLoc = renderSystem->ShaderGetModel();
+ GLint clipUniformLoc = renderSystem->ShaderGetClip();
+ GLint coordStepUniformLoc = renderSystem->ShaderGetCoordStep();
+ GLint matrixUniformLoc = renderSystem->ShaderGetMatrix();
CreateStaticVertexBuffers();
@@ -147,44 +163,6 @@ void CGUIFontTTFGL::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];
-
- GLuint VertexVBO;
-
- glGenBuffers(1, &VertexVBO);
- glBindBuffer(GL_ARRAY_BUFFER, VertexVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(SVertex) * vecVertices.size(), &vecVertices[0],
- GL_STATIC_DRAW);
-
- glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, x)));
- glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, r)));
- glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, u)));
-
- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDeleteBuffers(1, &VertexVBO);
- }
-
if (!m_vertexTrans.empty())
{
// Deal with the vertices that can be hardware clipped and therefore translated
@@ -211,14 +189,55 @@ void CGUIFontTTFGL::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);
@@ -245,13 +264,12 @@ void CGUIFontTTFGL::LastEnd()
glDrawElements(GL_TRIANGLES, 6 * count, GL_UNSIGNED_SHORT, 0);
}
-
- 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/GUIFontTTFGL.h b/xbmc/guilib/GUIFontTTFGL.h
index 22fbe6419b..e59a54a23c 100644
--- a/xbmc/guilib/GUIFontTTFGL.h
+++ b/xbmc/guilib/GUIFontTTFGL.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -55,4 +55,6 @@ private:
TextureStatus m_textureStatus{TEXTURE_VOID};
static bool m_staticVertexBufferCreated;
+
+ bool m_scissorClip{false};
};
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/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 fceb56bb7b..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"
diff --git a/xbmc/guilib/guiinfo/VideoGUIInfo.cpp b/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
index b4e61a3078..9e440b2539 100644
--- a/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
@@ -481,7 +481,7 @@ bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
case LISTITEM_FILENAME:
case LISTITEM_FILE_EXTENSION:
- if (item->IsVideoDb())
+ if (VIDEO::IsVideoDb(*item))
value = URIUtils::GetFileName(tag->m_strFileNameAndPath);
else if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
break;
@@ -496,7 +496,7 @@ bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
case LISTITEM_FOLDERNAME:
case LISTITEM_PATH:
- if (item->IsVideoDb())
+ if (VIDEO::IsVideoDb(*item))
{
if (item->m_bIsFolder)
value = tag->m_strPath;
@@ -517,7 +517,7 @@ bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
}
return true;
case LISTITEM_FILENAME_AND_PATH:
- if (item->IsVideoDb())
+ if (VIDEO::IsVideoDb(*item))
value = tag->m_strFileNameAndPath;
else if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
break;
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/ContextMenus.cpp b/xbmc/music/ContextMenus.cpp
index 9d146083bc..22df28acd2 100644
--- a/xbmc/music/ContextMenus.cpp
+++ b/xbmc/music/ContextMenus.cpp
@@ -19,10 +19,12 @@
#include "playlists/PlayListTypes.h"
#include "tags/MusicInfoTag.h"
#include "utils/Variant.h"
+#include "video/VideoFileItemClassify.h"
#include <utility>
using namespace CONTEXTMENU;
+using namespace KODI;
CMusicInfo::CMusicInfo(MediaType mediaType)
: CStaticContextMenuAction(19033), m_mediaType(std::move(mediaType))
@@ -32,8 +34,10 @@ CMusicInfo::CMusicInfo(MediaType mediaType)
bool CMusicInfo::IsVisible(const CFileItem& item) const
{
return (item.HasMusicInfoTag() && item.GetMusicInfoTag()->GetType() == m_mediaType) ||
- (m_mediaType == MediaTypeArtist && item.IsVideoDb() && item.HasProperty("artist_musicid")) ||
- (m_mediaType == MediaTypeAlbum && item.IsVideoDb() && item.HasProperty("album_musicid"));
+ (m_mediaType == MediaTypeArtist && VIDEO::IsVideoDb(item) &&
+ item.HasProperty("artist_musicid")) ||
+ (m_mediaType == MediaTypeAlbum && VIDEO::IsVideoDb(item) &&
+ item.HasProperty("album_musicid"));
}
bool CMusicInfo::Execute(const std::shared_ptr<CFileItem>& item) const
diff --git a/xbmc/music/GUIViewStateMusic.cpp b/xbmc/music/GUIViewStateMusic.cpp
index f14f5015e4..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"
@@ -23,8 +24,10 @@
#include "utils/FileExtensionProvider.h"
#include "utils/SortUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "view/ViewStateSettings.h"
+using namespace KODI;
using namespace XFILE;
using namespace MUSICDATABASEDIRECTORY;
@@ -503,7 +506,8 @@ CGUIViewStateWindowMusicNav::CGUIViewStateWindowMusicNav(const CFileItemList& it
}
else
{
- if (items.IsVideoDb() && items.Size() > (settings->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS)?1:0))
+ if (VIDEO::IsVideoDb(items) &&
+ items.Size() > (settings->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS) ? 1 : 0))
{
XFILE::VIDEODATABASEDIRECTORY::CQueryParams params;
XFILE::CVideoDatabaseDirectory::GetQueryParams(items[settings->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS) ? 1 : 0]->GetPath(), params);
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 1f0c60fb70..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"
@@ -875,7 +876,7 @@ bool IsItemPlayable(const CFileItem& item)
return false;
// Exclude all video library items
- if (item.IsVideoDb() || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/"))
+ if (IsVideoDb(item) || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/"))
return false;
// Exclude other components
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 0754c37e56..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"
@@ -299,7 +300,7 @@ void CGUIWindowMusicBase::OnItemInfo(int iItem)
CFileItemPtr item = m_vecItems->Get(iItem);
// Match visibility test of CMusicInfo::IsVisible
- if (item->IsVideoDb() && item->HasVideoInfoTag() &&
+ if (IsVideoDb(*item) && item->HasVideoInfoTag() &&
(item->HasProperty("artist_musicid") || item->HasProperty("album_musicid")))
{
// Music video artist or album (navigation by music > music video > artist))
@@ -731,7 +732,7 @@ bool CGUIWindowMusicBase::OnPlayMedia(int iItem, const std::string &player)
void CGUIWindowMusicBase::OnRetrieveMusicInfo(CFileItemList& items)
{
// No need to attempt to read music file tags for music videos
- if (items.IsVideoDb())
+ if (IsVideoDb(items))
return;
if (items.GetFolderCount()==items.Size() || items.IsMusicDb() ||
(!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MUSICFILES_USETAGS) && !items.IsCDDA()))
diff --git a/xbmc/music/windows/GUIWindowMusicNav.cpp b/xbmc/music/windows/GUIWindowMusicNav.cpp
index a544090204..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"
@@ -45,6 +46,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/dialogs/GUIDialogVideoInfo.h"
#include "video/windows/GUIWindowVideoNav.h"
#include "view/GUIViewState.h"
@@ -53,6 +55,7 @@ using namespace XFILE;
using namespace PLAYLIST;
using namespace MUSICDATABASEDIRECTORY;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
#define CONTROL_BTNVIEWASICONS 2
#define CONTROL_BTNSORTBY 3
@@ -386,7 +389,7 @@ bool CGUIWindowMusicNav::GetDirectory(const std::string &strDirectory, CFileItem
}
// update our content in the info manager
- if (StringUtils::StartsWithNoCase(strDirectory, "videodb://") || items.IsVideoDb())
+ if (StringUtils::StartsWithNoCase(strDirectory, "videodb://") || IsVideoDb(items))
{
CVideoDatabaseDirectory dir;
VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(items.GetPath());
@@ -624,8 +627,8 @@ void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &butt
if (!item->IsParentFolder() && !dir.IsAllItem(item->GetPath()))
{
- if (item->m_bIsFolder && !item->IsVideoDb() &&
- !item->IsPlugin() && !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
+ if (item->m_bIsFolder && !IsVideoDb(*item) && !item->IsPlugin() &&
+ !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
{
if (item->IsAlbum())
// enable query all albums button only in album view
@@ -718,7 +721,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
case CONTEXT_BUTTON_INFO:
{
- if (!item->IsVideoDb())
+ if (!IsVideoDb(*item))
return CGUIWindowMusicBase::OnContextButton(itemNumber,button);
// music videos - artists
@@ -807,7 +810,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
}
case CONTEXT_BUTTON_RENAME:
- if (!item->IsVideoDb() && !item->IsReadOnly())
+ if (!IsVideoDb(*item) && !item->IsReadOnly())
OnRenameItem(itemNumber);
CGUIDialogVideoInfo::UpdateVideoItemTitle(item);
@@ -823,7 +826,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
if (gui && gui->ConfirmDelete(item->GetPath()))
CFileUtils::DeleteItem(item);
}
- else if (!item->IsVideoDb())
+ else if (!IsVideoDb(*item))
OnDeleteItem(itemNumber);
else
{
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/UPnPInternal.cpp b/xbmc/network/upnp/UPnPInternal.cpp
index c9a3bacd4c..f03cab5e27 100644
--- a/xbmc/network/upnp/UPnPInternal.cpp
+++ b/xbmc/network/upnp/UPnPInternal.cpp
@@ -205,13 +205,13 @@ NPT_String GetMimeType(const CFileItem& item, const PLT_HttpRequestContext* cont
/* fallback to generic mime type if not found */
if (mime.IsEmpty())
{
- if (VIDEO::IsVideo(item) || item.IsVideoDb())
+ if (VIDEO::IsVideo(item) || VIDEO::IsVideoDb(item))
mime = "video/" + ext;
else if (item.IsAudio() || item.IsMusicDb())
mime = "audio/" + ext;
else if (item.IsPicture())
mime = "image/" + ext;
- else if (item.IsSubtitle())
+ else if (VIDEO::IsSubtitle(item))
mime = "text/" + ext;
}
@@ -530,7 +530,7 @@ PLT_MediaObject* BuildObject(CFileItem& item,
PopulateObjectFromTag(*tag, *object, &file_path, &resource, quirks, upnp_service);
}
}
- else if (item.IsVideoDb() || VIDEO::IsVideo(item))
+ else if (VIDEO::IsVideoDb(item) || VIDEO::IsVideo(item))
{
object->m_ObjectClass.type = "object.item.videoItem";
@@ -674,7 +674,7 @@ PLT_MediaObject* BuildObject(CFileItem& item,
break;
}
}
- else if (item.IsVideoDb())
+ else if (VIDEO::IsVideoDb(item))
{
VIDEODATABASEDIRECTORY::NODE_TYPE node =
CVideoDatabaseDirectory::GetDirectoryType(item.GetPath());
diff --git a/xbmc/network/upnp/UPnPPlayer.cpp b/xbmc/network/upnp/UPnPPlayer.cpp
index 103581afe2..93ef3a58a9 100644
--- a/xbmc/network/upnp/UPnPPlayer.cpp
+++ b/xbmc/network/upnp/UPnPPlayer.cpp
@@ -225,7 +225,7 @@ int CUPnPPlayer::PlayFile(const CFileItem& file,
NPT_CHECK_POINTER_LABEL_SEVERE(m_delegate, failed);
- if (file.IsVideoDb())
+ if (VIDEO::IsVideoDb(file))
thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
else if (item.IsMusicDb())
thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());
@@ -419,7 +419,7 @@ bool CUPnPPlayer::QueueNextFile(const CFileItem& file)
NPT_String path(file.GetPath().c_str());
NPT_String tmp;
- if (file.IsVideoDb())
+ if (VIDEO::IsVideoDb(file))
thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
else if (item.IsMusicDb())
thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());
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 3618708a5d..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"
@@ -38,6 +39,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoLibraryQueue.h"
#include "video/VideoThumbLoader.h"
#include "view/GUIViewState.h"
@@ -49,6 +51,7 @@
NPT_SET_LOCAL_LOGGER("xbmc.upnp.server")
using namespace ANNOUNCEMENT;
+using namespace KODI::VIDEO;
using namespace XFILE;
using KODI::UTILITY::CDigest;
@@ -713,7 +716,7 @@ NPT_Result CUPnPServer::OnBrowseMetadata(PLT_ActionReference& action,
parent = "sources://video/"; // this can only match video sources
}
- if (item->IsVideoDb())
+ if (IsVideoDb(*item))
{
thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
}
@@ -1306,7 +1309,7 @@ NPT_Result CUPnPServer::OnUpdateObject(PLT_ActionReference& action,
NPT_CHECK_LABEL(FindServiceById("urn:upnp-org:serviceId:ContentDirectory", service), error);
NPT_CHECK_LABEL(service->PauseEventing(), error);
- if (updated.IsVideoDb())
+ if (IsVideoDb(updated))
{
CVideoDatabase db;
NPT_CHECK_LABEL(!db.Open(), error);
@@ -1408,7 +1411,7 @@ NPT_Result CUPnPServer::OnUpdateObject(PLT_ActionReference& action,
if (updatelisting)
{
updated.SetPath(path);
- if (updated.IsVideoDb())
+ if (IsVideoDb(updated))
CUtil::DeleteVideoDatabaseDirectoryCache();
else if (updated.IsMusicDb())
CUtil::DeleteMusicDatabaseDirectoryCache();
@@ -1525,7 +1528,7 @@ NPT_Result CUPnPServer::ServeFile(const NPT_HttpRequest& request,
void CUPnPServer::DefaultSortItems(CFileItemList& items)
{
CGUIViewState* viewState =
- CGUIViewState::GetViewState(items.IsVideoDb() ? WINDOW_VIDEO_NAV : -1, items);
+ CGUIViewState::GetViewState(IsVideoDb(items) ? WINDOW_VIDEO_NAV : -1, items);
if (viewState)
{
SortDescription sorting = viewState->GetSortMethod();
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/XBMCApp.cpp b/xbmc/platform/android/activity/XBMCApp.cpp
index 30e6028fb9..437c7371d9 100644
--- a/xbmc/platform/android/activity/XBMCApp.cpp
+++ b/xbmc/platform/android/activity/XBMCApp.cpp
@@ -47,6 +47,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "windowing/GraphicContext.h"
#include "windowing/WinEvents.h"
@@ -117,6 +118,7 @@
using namespace ANNOUNCEMENT;
using namespace jni;
using namespace KODI::GUILIB;
+using namespace KODI::VIDEO;
using namespace std::chrono_literals;
std::shared_ptr<CNativeWindow> CNativeWindow::CreateFromSurface(CJNISurfaceHolder holder)
@@ -1451,7 +1453,7 @@ void CXBMCApp::onNewIntent(CJNIIntent intent)
else
{
CFileItem* item = new CFileItem(targetFile, false);
- if (item->IsVideoDb())
+ if (IsVideoDb(*item))
{
*(item->GetVideoInfoTag()) = XFILE::CVideoDatabaseFile::GetVideoTag(CURL(item->GetPath()));
item->SetPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
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/gl/GLShader.cpp b/xbmc/rendering/gl/GLShader.cpp
index e91af97b56..77dd6e4ed2 100644
--- a/xbmc/rendering/gl/GLShader.cpp
+++ b/xbmc/rendering/gl/GLShader.cpp
@@ -1,12 +1,11 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-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.
*/
-
#include "GLShader.h"
#include "ServiceBroker.h"
@@ -49,6 +48,9 @@ void CGLShader::OnCompiledAndLinked()
// Variables passed directly to the Vertex shader
m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
+ 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/gl/GLShader.h b/xbmc/rendering/gl/GLShader.h
index d5b82f3a07..791c44926b 100644
--- a/xbmc/rendering/gl/GLShader.h
+++ b/xbmc/rendering/gl/GLShader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -27,6 +27,9 @@ public:
GLint GetCord1Loc() {return m_hCord1;}
GLint GetUniColLoc() {return m_hUniCol;}
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; }
@@ -39,6 +42,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/gl/RenderSystemGL.cpp b/xbmc/rendering/gl/RenderSystemGL.cpp
index 4b80014d41..516027ef49 100644
--- a/xbmc/rendering/gl/RenderSystemGL.cpp
+++ b/xbmc/rendering/gl/RenderSystemGL.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -682,13 +682,24 @@ void CRenderSystemGL::InitialiseShaders()
CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_multi.glsl - compile and link failed");
}
- m_pShader[ShaderMethodGL::SM_FONTS] =
- std::make_unique<CGLShader>("gl_shader_frag_fonts.glsl", defines);
+ m_pShader[ShaderMethodGL::SM_FONTS] = std::make_unique<CGLShader>(
+ "gl_shader_vert_simple.glsl", "gl_shader_frag_fonts.glsl", defines);
if (!m_pShader[ShaderMethodGL::SM_FONTS]->CompileAndLink())
{
m_pShader[ShaderMethodGL::SM_FONTS]->Free();
m_pShader[ShaderMethodGL::SM_FONTS].reset();
- CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_fonts.glsl - compile and link failed");
+ CLog::Log(LOGERROR, "GUI Shader gl_shader_vert_simple.glsl + gl_shader_frag_fonts.glsl - "
+ "compile and link failed");
+ }
+
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP] =
+ std::make_unique<CGLShader>("gl_shader_vert_clip.glsl", "gl_shader_frag_fonts.glsl", defines);
+ if (!m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->CompileAndLink())
+ {
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP].reset();
+ CLog::Log(LOGERROR, "GUI Shader gl_shader_vert_clip.glsl + gl_shader_frag_fonts.glsl - compile "
+ "and link failed");
}
m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND] =
@@ -732,6 +743,10 @@ void CRenderSystemGL::ReleaseShaders()
m_pShader[ShaderMethodGL::SM_FONTS]->Free();
m_pShader[ShaderMethodGL::SM_FONTS].reset();
+ if (m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP])
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP].reset();
+
if (m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND])
m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND]->Free();
m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND].reset();
@@ -811,6 +826,30 @@ GLint CRenderSystemGL::ShaderGetModel()
return -1;
}
+GLint CRenderSystemGL::ShaderGetMatrix()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetMatrixLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGL::ShaderGetClip()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderClipLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGL::ShaderGetCoordStep()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderCoordStepLoc();
+
+ return -1;
+}
+
std::string CRenderSystemGL::GetShaderPath(const std::string &filename)
{
std::string path = "GL/1.2/";
diff --git a/xbmc/rendering/gl/RenderSystemGL.h b/xbmc/rendering/gl/RenderSystemGL.h
index 191c97ff96..520c552e45 100644
--- a/xbmc/rendering/gl/RenderSystemGL.h
+++ b/xbmc/rendering/gl/RenderSystemGL.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -27,6 +27,7 @@ enum class ShaderMethodGL
SM_TEXTURE_LIM,
SM_MULTI,
SM_FONTS,
+ SM_FONTS_SHADER_CLIP,
SM_TEXTURE_NOBLEND,
SM_MULTI_BLENDCOLOR,
SM_MAX
@@ -52,6 +53,7 @@ private:
{ShaderMethodGL::SM_TEXTURE_LIM, "texture limited"},
{ShaderMethodGL::SM_MULTI, "multi"},
{ShaderMethodGL::SM_FONTS, "fonts"},
+ {ShaderMethodGL::SM_FONTS_SHADER_CLIP, "fonts with vertex shader based clipping"},
{ShaderMethodGL::SM_TEXTURE_NOBLEND, "texture no blending"},
{ShaderMethodGL::SM_MULTI_BLENDCOLOR, "multi blend colour"},
});
@@ -114,6 +116,9 @@ public:
GLint ShaderGetCoord1();
GLint ShaderGetUniCol();
GLint ShaderGetModel();
+ GLint ShaderGetMatrix();
+ GLint ShaderGetClip();
+ GLint ShaderGetCoordStep();
protected:
virtual void SetVSyncImpl(bool enable) = 0;
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/ExecString.cpp b/xbmc/utils/ExecString.cpp
index cd392c26db..f4767ff958 100644
--- a/xbmc/utils/ExecString.cpp
+++ b/xbmc/utils/ExecString.cpp
@@ -18,8 +18,11 @@
#include "utils/StringUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
+using namespace KODI;
+
CExecString::CExecString(const std::string& execString)
{
m_valid = Parse(execString);
@@ -123,7 +126,7 @@ bool CExecString::Parse(const CFileItem& item, const std::string& contextWindow)
Build("StartAndroidActivity", {StringUtils::Paramify(item.GetPath().substr(26))});
else // assume a media file
{
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(item) && item.HasVideoInfoTag())
BuildPlayMedia(item, StringUtils::Paramify(item.GetVideoInfoTag()->m_strFileNameAndPath));
else if (item.IsMusicDb() && item.HasMusicInfoTag())
BuildPlayMedia(item, StringUtils::Paramify(item.GetMusicInfoTag()->GetURL()));
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/Geometry.h b/xbmc/utils/Geometry.h
index 31557fc647..1bf4624d06 100644
--- a/xbmc/utils/Geometry.h
+++ b/xbmc/utils/Geometry.h
@@ -281,6 +281,11 @@ public:
return (x1 <= point.x && point.x <= x2 && y1 <= point.y && point.y <= y2);
};
+ constexpr bool Intersects(const this_type& rect) const
+ {
+ return (x1 < rect.x2 && x2 > rect.x1 && y1 < rect.y2 && y2 > rect.y1);
+ };
+
this_type& operator-=(const point_type &point) XBMC_FORCE_INLINE
{
x1 -= point.x;
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 3f47f61e65..aeb479a4bb 100644
--- a/xbmc/utils/SaveFileStateJob.cpp
+++ b/xbmc/utils/SaveFileStateJob.cpp
@@ -40,7 +40,7 @@ void CSaveFileState::DoWork(CFileItem& item,
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 (item.HasVideoInfoTag() && item.IsVideoDb())
+ 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
else if (item.HasProperty("original_listitem_url"))
{
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 a7a724e082..1ab69f504e 100644
--- a/xbmc/video/ContextMenus.cpp
+++ b/xbmc/video/ContextMenus.cpp
@@ -24,6 +24,7 @@
#include "utils/ExecString.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoManagerTypes.h"
#include "video/VideoUtils.h"
@@ -35,6 +36,8 @@
#include <utility>
+using namespace KODI::VIDEO;
+
namespace CONTEXTMENU
{
@@ -87,7 +90,7 @@ bool CVideoMarkWatched::IsVisible(const CFileItem& item) const
if (item.m_bIsFolder) // Only allow video db content, video and recording folders to be updated recursively
{
if (item.HasVideoInfoTag())
- return item.IsVideoDb();
+ return IsVideoDb(item);
else if (item.GetProperty("IsVideoFolder").asBoolean())
return true;
else
@@ -116,7 +119,7 @@ bool CVideoMarkUnWatched::IsVisible(const CFileItem& item) const
if (item.m_bIsFolder) // Only allow video db content, video and recording folders to be updated recursively
{
if (item.HasVideoInfoTag())
- return item.IsVideoDb();
+ return IsVideoDb(item);
else if (item.GetProperty("IsVideoFolder").asBoolean())
return true;
else
@@ -237,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
@@ -272,7 +275,7 @@ std::vector<std::string> GetPlayers(const CPlayerCoreFactory& playerCoreFactory,
const CFileItem& item)
{
std::vector<std::string> players;
- if (item.IsVideoDb())
+ if (IsVideoDb(item))
{
//! @todo CPlayerCoreFactory and classes called from there do not handle dyn path correctly.
CFileItem item2{item};
@@ -351,7 +354,7 @@ void SetPathAndPlay(const std::shared_ptr<CFileItem>& item, PlayMode mode)
else
{
const auto itemCopy{std::make_shared<CFileItem>(*item)};
- if (itemCopy->IsVideoDb())
+ if (IsVideoDb(*itemCopy))
{
if (!itemCopy->m_bIsFolder)
{
@@ -431,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())
@@ -453,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 278bec56b4..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"
@@ -21,8 +22,10 @@
#include "settings/SettingsComponent.h"
#include "utils/FileExtensionProvider.h"
#include "utils/SortUtils.h"
+#include "video/VideoFileItemClassify.h"
#include "view/ViewStateSettings.h"
+using namespace KODI::VIDEO;
using namespace XFILE;
using namespace VIDEODATABASEDIRECTORY;
@@ -69,7 +72,7 @@ CGUIViewStateWindowVideoNav::CGUIViewStateWindowVideoNav(const CFileItemList& it
SetSortOrder(SortOrderNone);
}
- else if (items.IsVideoDb())
+ else if (IsVideoDb(items))
{
NODE_TYPE NodeType=CVideoDatabaseDirectory::GetDirectoryChildType(items.GetPath());
CQueryParams params;
@@ -337,7 +340,7 @@ CGUIViewStateWindowVideoNav::CGUIViewStateWindowVideoNav(const CFileItemList& it
void CGUIViewStateWindowVideoNav::SaveViewState()
{
- if (m_items.IsVideoDb())
+ if (IsVideoDb(m_items))
{
NODE_TYPE NodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_items.GetPath());
CQueryParams params;
diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp
index 1372e54173..a40b707a3f 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"
@@ -52,6 +53,7 @@
#include "utils/XMLUtils.h"
#include "utils/log.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoLibraryQueue.h"
#include "video/VideoManagerTypes.h"
@@ -70,6 +72,7 @@ using namespace VIDEO;
using namespace ADDON;
using namespace KODI::MESSAGING;
using namespace KODI::GUILIB;
+using namespace KODI::VIDEO;
//********************************************************************************************************************************
CVideoDatabase::CVideoDatabase(void) = default;
@@ -1040,7 +1043,7 @@ int CVideoDatabase::AddFile(const std::string& strFileNameAndPath,
int CVideoDatabase::AddFile(const CFileItem& item)
{
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
{
const auto videoInfoTag = item.GetVideoInfoTag();
if (videoInfoTag->m_iFileId != -1)
diff --git a/xbmc/video/VideoFileItemClassify.cpp b/xbmc/video/VideoFileItemClassify.cpp
index 65a9253f68..d57306013d 100644
--- a/xbmc/video/VideoFileItemClassify.cpp
+++ b/xbmc/video/VideoFileItemClassify.cpp
@@ -10,13 +10,74 @@
#include "FileItem.h"
#include "ServiceBroker.h"
+#include "URL.h"
#include "utils/FileExtensionProvider.h"
+#include "utils/FileUtils.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoInfoTag.h"
namespace KODI::VIDEO
{
+bool IsBDFile(const CFileItem& item)
+{
+ const std::string strFileName = URIUtils::GetFileName(item.GetDynPath());
+ return (StringUtils::EqualsNoCase(strFileName, "index.bdmv") ||
+ StringUtils::EqualsNoCase(strFileName, "MovieObject.bdmv") ||
+ StringUtils::EqualsNoCase(strFileName, "INDEX.BDM") ||
+ StringUtils::EqualsNoCase(strFileName, "MOVIEOBJ.BDM"));
+}
+
+bool IsDiscStub(const CFileItem& item)
+{
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
+ {
+ CFileItem dbItem(item.m_bIsFolder ? item.GetVideoInfoTag()->m_strPath
+ : item.GetVideoInfoTag()->m_strFileNameAndPath,
+ item.m_bIsFolder);
+ return IsDiscStub(dbItem);
+ }
+
+ return URIUtils::HasExtension(item.GetPath(),
+ CServiceBroker::GetFileExtensionProvider().GetDiscStubExtensions());
+}
+
+bool IsDVDFile(const CFileItem& item, bool bVobs /*= true*/, bool bIfos /*= true*/)
+{
+ const std::string strFileName = URIUtils::GetFileName(item.GetDynPath());
+ if (bIfos)
+ {
+ if (StringUtils::EqualsNoCase(strFileName, "video_ts.ifo"))
+ return true;
+ if (StringUtils::StartsWithNoCase(strFileName, "vts_") &&
+ StringUtils::EndsWithNoCase(strFileName, "_0.ifo") && strFileName.length() == 12)
+ return true;
+ }
+ if (bVobs)
+ {
+ if (StringUtils::EqualsNoCase(strFileName, "video_ts.vob"))
+ return true;
+ if (StringUtils::StartsWithNoCase(strFileName, "vts_") &&
+ StringUtils::EndsWithNoCase(strFileName, ".vob"))
+ return true;
+ }
+
+ return false;
+}
+
+bool IsProtectedBlurayDisc(const CFileItem& item)
+{
+ const std::string path = URIUtils::AddFileToFolder(item.GetPath(), "AACS", "Unit_Key_RO.inf");
+ return CFileUtils::Exists(path);
+}
+
+bool IsSubtitle(const CFileItem& item)
+{
+ return URIUtils::HasExtension(item.GetPath(),
+ CServiceBroker::GetFileExtensionProvider().GetSubtitleExtensions());
+}
+
bool IsVideo(const CFileItem& item)
{
/* check preset mime type */
@@ -62,4 +123,25 @@ 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());
+}
+
+bool IsVideoExtrasFolder(const CFileItem& item)
+{
+ return item.m_bIsFolder &&
+ StringUtils::EqualsNoCase(URIUtils::GetFileOrFolderName(item.GetPath()), "extras");
+}
+
} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoFileItemClassify.h b/xbmc/video/VideoFileItemClassify.h
index 337a0696c6..55e5aeded7 100644
--- a/xbmc/video/VideoFileItemClassify.h
+++ b/xbmc/video/VideoFileItemClassify.h
@@ -13,9 +13,35 @@ class CFileItem;
namespace KODI::VIDEO
{
+//! \brief Check whether an item is a blu-ray file.
+bool IsBDFile(const CFileItem& item);
+
+//! \brief Check whether an item is a disc stub.
+bool IsDiscStub(const CFileItem& item);
+
+//! \brief Check whether an item is a DVD file.
+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 Check whether an item is a subtitle file.
+bool IsSubtitle(const CFileItem& item);
+
//! \brief Check whether an item is a video item.
//! \details Note that this returns true for anything with a video info tag,
//! 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);
+
+//! \brief Check whether an item is a video extras folder item.
+bool IsVideoExtrasFolder(const CFileItem& item);
+
} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoGeneratedImageFileLoader.cpp b/xbmc/video/VideoGeneratedImageFileLoader.cpp
index e39f5960cf..6ef1b93ef9 100644
--- a/xbmc/video/VideoGeneratedImageFileLoader.cpp
+++ b/xbmc/video/VideoGeneratedImageFileLoader.cpp
@@ -17,8 +17,11 @@
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
+using namespace KODI::VIDEO;
+
bool VIDEO::CVideoGeneratedImageFileLoader::CanLoad(const std::string& specialType) const
{
return specialType == "video";
@@ -29,7 +32,7 @@ namespace
void SetupRarOptions(CFileItem& item, const std::string& path)
{
std::string path2(path);
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
path2 = item.GetVideoInfoTag()->m_strFileNameAndPath;
CURL url(path2);
std::string opts = url.GetOptions();
@@ -40,7 +43,7 @@ void SetupRarOptions(CFileItem& item, const std::string& path)
else
opts = "?flags=8";
url.SetOptions(opts);
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
item.GetVideoInfoTag()->m_strFileNameAndPath = url.Get();
else
item.SetPath(url.Get());
diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp
index b5559cea69..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"
@@ -415,7 +416,7 @@ namespace VIDEO
break;
// add video extras to library
- if (foundSomething && !m_ignoreVideoExtras && pItem->IsVideoExtras())
+ if (foundSomething && !m_ignoreVideoExtras && IsVideoExtrasFolder(*pItem))
{
if (AddVideoExtras(items, content, pItem->GetPath()))
{
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 155fcb9da6..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,
@@ -554,7 +555,7 @@ std::string CVideoThumbLoader::GetLocalArt(const CFileItem &item, const std::str
std::string CVideoThumbLoader::GetEmbeddedThumbURL(const CFileItem &item)
{
std::string path(item.GetPath());
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
path = item.GetVideoInfoTag()->m_strFileNameAndPath;
if (URIUtils::IsStack(path))
path = CStackDirectory::GetFirstStackedFile(path);
@@ -600,7 +601,7 @@ void CVideoThumbLoader::DetectAndAddMissingItemData(CFileItem &item)
if (stereoMode.empty())
{
std::string path = item.GetPath();
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
path = item.GetVideoInfoTag()->GetPath();
// check for custom stereomode setting in video settings
diff --git a/xbmc/video/VideoUtils.cpp b/xbmc/video/VideoUtils.cpp
index d3ab9fed70..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"
@@ -29,6 +30,8 @@
#include <cstdint>
#include <vector>
+using namespace KODI::VIDEO;
+
namespace
{
VIDEO_UTILS::ResumeInformation GetFolderItemResumeInformation(const CFileItem& item)
@@ -125,13 +128,13 @@ VIDEO_UTILS::ResumeInformation GetNonFolderItemResumeInformation(const CFileItem
}
std::string path = item.GetPath();
- if (item.IsVideoDb() || item.IsDVD())
+ if (IsVideoDb(item) || item.IsDVD())
{
if (item.HasVideoInfoTag())
{
path = item.GetVideoInfoTag()->m_strFileNameAndPath;
}
- else if (item.IsVideoDb())
+ else if (IsVideoDb(item))
{
// Obtain path+filename from video db
XFILE::VIDEODATABASEDIRECTORY::CQueryParams params;
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 59daa631de..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"
@@ -51,6 +52,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoScanner.h"
#include "video/VideoInfoTag.h"
#include "video/VideoItemArtworkHandler.h"
@@ -71,6 +73,7 @@
using namespace XFILE::VIDEODATABASEDIRECTORY;
using namespace XFILE;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
#define CONTROL_IMAGE 3
#define CONTROL_TEXTAREA 4
@@ -279,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() ||
@@ -1067,7 +1070,8 @@ std::string CGUIDialogVideoInfo::GetThumbnail() const
int CGUIDialogVideoInfo::ManageVideoItem(const std::shared_ptr<CFileItem>& item)
{
- if (item == nullptr || !item->IsVideoDb() || !item->HasVideoInfoTag() || item->GetVideoInfoTag()->m_iDbId < 0)
+ if (item == nullptr || !IsVideoDb(*item) || !item->HasVideoInfoTag() ||
+ item->GetVideoInfoTag()->m_iDbId < 0)
return -1;
CVideoDatabase database;
@@ -1078,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))
@@ -1113,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
@@ -1139,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 76eeb807d5..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"
@@ -200,7 +201,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
items.Sort(sortDesc);
}
- if (items.GetContent().empty() && !items.IsVideoDb() && !items.IsVirtualDirectoryRoot() &&
+ if (items.GetContent().empty() && !IsVideoDb(items) && !items.IsVirtualDirectoryRoot() &&
!items.IsSourcesPath() && !items.IsLibraryFolder())
{
CVideoDatabase db;
@@ -302,7 +303,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
// a playable python files
m_queuedItems.Add(item);
}
- else if (item->IsVideoDb())
+ else if (IsVideoDb(*item))
{
// this case is needed unless we allow IsVideo() to return true for videodb items,
// but then we have issues with playlists of videodb items
@@ -556,7 +557,7 @@ bool IsItemPlayable(const CFileItem& item)
return false;
if (item.m_bIsFolder &&
- (item.IsVideoDb() || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/")))
+ (IsVideoDb(item) || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/")))
{
// Exclude top level nodes - eg can't play 'genres' just a specific genre etc
const XFILE::VIDEODATABASEDIRECTORY::NODE_TYPE node =
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 e6ece8f03c..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"
@@ -21,9 +22,11 @@
#include "utils/StringUtils.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoManagerTypes.h"
#include "video/VideoThumbLoader.h"
+using namespace KODI::VIDEO;
using namespace VIDEO::GUILIB;
namespace
@@ -278,17 +281,3 @@ std::shared_ptr<CFileItem> CVideoVersionHelper::ChooseVideoFromAssets(
return item;
}
-
-bool VIDEO::IsVideoAssetFile(const CFileItem& item)
-{
- if (item.m_bIsFolder || !item.IsVideoDb())
- 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 5824bec21a..3fae8d23a0 100644
--- a/xbmc/video/test/TestVideoFileItemClassify.cpp
+++ b/xbmc/video/test/TestVideoFileItemClassify.cpp
@@ -8,10 +8,15 @@
#include "FileItem.h"
#include "ServiceBroker.h"
+#include "filesystem/Directory.h"
+#include "filesystem/File.h"
#include "games/tags/GameInfoTag.h"
#include "music/tags/MusicInfoTag.h"
#include "pictures/PictureInfoTag.h"
+#include "test/TestUtils.h"
#include "utils/FileExtensionProvider.h"
+#include "utils/FileUtils.h"
+#include "utils/URIUtils.h"
#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
@@ -21,6 +26,47 @@
using namespace KODI;
+struct StubDefinition
+{
+ StubDefinition(const std::string& path,
+ bool res = true,
+ const std::string& tagPath = "",
+ bool isFolder = false)
+ : item(path, isFolder), result(res)
+ {
+ if (!tagPath.empty())
+ {
+ if (isFolder)
+ item.GetVideoInfoTag()->m_strPath = tagPath;
+ else
+ item.GetVideoInfoTag()->m_strFileNameAndPath = tagPath;
+ }
+ }
+
+ CFileItem item;
+ bool result;
+};
+
+class DiscStubTest : public testing::WithParamInterface<StubDefinition>, public testing::Test
+{
+};
+
+TEST_P(DiscStubTest, IsDiscStub)
+{
+ EXPECT_EQ(VIDEO::IsDiscStub(GetParam().item), GetParam().result);
+}
+
+const auto discstub_tests = std::array{
+ StubDefinition{"/home/user/test.disc"},
+ StubDefinition{"videodb://foo/bar", true, "/home/user/test.disc"},
+ StubDefinition{"videodb://foo/bar", false, "/home/user/test.disc", true},
+ StubDefinition{"/home/user/test.avi", false},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestVideoFileItemClassify,
+ DiscStubTest,
+ testing::ValuesIn(discstub_tests));
+
struct VideoClassifyTest
{
VideoClassifyTest(const std::string& path,
@@ -90,3 +136,84 @@ TEST(TestVideoFileItemClassify, VideoExtensions)
EXPECT_TRUE(VIDEO::IsVideo(CFileItem(ext, false)));
}
}
+
+TEST(TestVideoFileItemClassify, IsBDFile)
+{
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("/home/foo/index.BDMV", false)));
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("smb://foo/bar/index.bdm", false)));
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("ftp://foo:bar@foobar.com/movieobject.BDMV", false)));
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("https://foobar.com/movieobj.bdm", false)));
+ EXPECT_FALSE(VIDEO::IsBDFile(CFileItem("https://foobar.com/movieobject.not", false)));
+}
+
+TEST(TestVideoFileItemClassify, IsDVDFile)
+{
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.vob", false), true, false));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.VOB", false), true, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_TS.vob", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.VOb", false), false, true));
+
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_yo_0.vob", false), true, false));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_0_ifo.vob", false), true, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_123456_0.vob", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_qwerty_0.VOB", false), false, true));
+
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), false, true));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), true, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), true, false));
+
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_ab_0.ifo", false), false, true));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_ab_0.ifo", false), false, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_ab_0.ifo", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_ab_0.ifo", false), false, false));
+}
+
+TEST(TestVideoFileItemClassify, IsProtectedBlurayDisc)
+{
+ const auto temp_file = CXBMCTestUtils::Instance().CreateTempFile("bluraytest");
+ const std::string dir = CXBMCTestUtils::Instance().TempFileDirectory(temp_file);
+ CFileUtils::DeleteItem(URIUtils::AddFileToFolder(dir, "AACS", "Unit_Key_RO.inf"));
+ EXPECT_FALSE(VIDEO::IsProtectedBlurayDisc(CFileItem(dir, true)));
+ XFILE::CDirectory::Create(URIUtils::AddFileToFolder(dir, "AACS"));
+ XFILE::CFile inf_file;
+ inf_file.OpenForWrite(URIUtils::AddFileToFolder(dir, "AACS", "Unit_Key_RO.inf"));
+ inf_file.Close();
+ EXPECT_TRUE(VIDEO::IsProtectedBlurayDisc(CFileItem(dir, true)));
+ CFileUtils::DeleteItem(URIUtils::AddFileToFolder(dir, "AACS", "Unit_Key_RO.inf"));
+ CXBMCTestUtils::Instance().DeleteTempFile(temp_file);
+}
+
+TEST(TestVideoFileItemClassify, IsSubtitle)
+{
+ const auto& exts = CServiceBroker::GetFileExtensionProvider().GetSubtitleExtensions();
+ for (const auto& ext : StringUtils::Split(exts, "|"))
+ {
+ if (!ext.empty())
+ EXPECT_TRUE(VIDEO::IsSubtitle(CFileItem("random" + ext, false)));
+ }
+
+ 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)));
+ EXPECT_TRUE(VIDEO::IsVideoDb(CFileItem("videodb://1/2/", true)));
+ EXPECT_FALSE(VIDEO::IsVideoDb(CFileItem("/videodb/home/foo/Extraordinary/", true)));
+}
+
+TEST(TestVideoFileItemClassify, IsVideoExtrasFolder)
+{
+ EXPECT_TRUE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/Extras/", true)));
+ EXPECT_TRUE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/extras/", true)));
+ EXPECT_FALSE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/Extraordinary/", true)));
+ EXPECT_FALSE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/Extras/abc.mkv", false)));
+}
diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp
index 7d57d7f6e4..13c1bd25d2 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"
@@ -225,13 +226,13 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
return false;
// Movie set
- if (fileItem.m_bIsFolder && fileItem.IsVideoDb() &&
+ if (fileItem.m_bIsFolder && IsVideoDb(fileItem) &&
fileItem.GetPath() != "videodb://movies/sets/" &&
StringUtils::StartsWith(fileItem.GetPath(), "videodb://movies/sets/"))
return ShowInfoAndRefresh(std::make_shared<CFileItem>(fileItem), nullptr);
// Music video. Match visibility test of CMusicInfo::IsVisible
- if (fileItem.IsVideoDb() && fileItem.HasVideoInfoTag() &&
+ if (IsVideoDb(fileItem) && fileItem.HasVideoInfoTag() &&
(fileItem.HasProperty("artist_musicid") || fileItem.HasProperty("album_musicid")))
{
CGUIDialogMusicInfo::ShowFor(std::make_shared<CFileItem>(fileItem).get());
@@ -239,7 +240,7 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
}
std::string strDir;
- if (fileItem.IsVideoDb() && fileItem.HasVideoInfoTag() &&
+ if (IsVideoDb(fileItem) && fileItem.HasVideoInfoTag() &&
!fileItem.GetVideoInfoTag()->m_strPath.empty())
strDir = fileItem.GetVideoInfoTag()->m_strPath;
else
@@ -270,7 +271,7 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
return true;
CFileItem item(fileItem);
- if ((item.IsVideoDb() && item.HasVideoInfoTag()) ||
+ if ((IsVideoDb(item) && item.HasVideoInfoTag()) ||
(item.HasVideoInfoTag() && item.GetVideoInfoTag()->m_iDbId != -1))
{
if (item.GetVideoInfoTag()->m_type == MediaTypeSeason)
@@ -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;
@@ -443,9 +444,9 @@ bool CGUIWindowVideoBase::ShowInfo(const CFileItemPtr& item2, const ScraperPtr&
{
item = pDlgInfo->GetCurrentListItem();
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (IsVideoDb(*item) && item->HasVideoInfoTag())
item->SetPath(item->GetVideoInfoTag()->GetPath());
- else if (!item->IsVideoDb() && item->m_bIsFolder)
+ else if (!IsVideoDb(*item) && item->m_bIsFolder)
{
// Info on folder containing a movie needs dyn path as path for refresh with correct name
//! @todo get rid of "videos with versions as folder" hack to be able to fix in CFileItem::GetBaseMoviePath()
@@ -494,7 +495,7 @@ bool CGUIWindowVideoBase::ShowInfo(const CFileItemPtr& item2, const ScraperPtr&
{
item = pDlgInfo->GetCurrentListItem();
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (IsVideoDb(*item) && item->HasVideoInfoTag())
item->SetPath(item->GetVideoInfoTag()->GetPath());
}
listNeedsUpdating = true;
@@ -802,7 +803,7 @@ void CGUIWindowVideoBase::GetContextButtons(int itemNumber, CContextButtons &but
if (!item->IsParentFolder())
{
std::string path(item->GetPath());
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (IsVideoDb(*item) && item->HasVideoInfoTag())
path = item->GetVideoInfoTag()->m_strFileNameAndPath;
if (!item->IsPath("add") && !item->IsPlugin() &&
@@ -913,13 +914,13 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
if (!item)
return false;
- if (item->IsVideoDb() && (!item->m_bIsFolder || item->GetVideoInfoTag()->m_strPath.empty()))
+ if (IsVideoDb(*item) && (!item->m_bIsFolder || item->GetVideoInfoTag()->m_strPath.empty()))
return false;
if (item->m_bIsFolder)
{
const std::string strPath =
- item->IsVideoDb() ? item->GetVideoInfoTag()->m_strPath : item->GetPath();
+ IsVideoDb(*item) ? item->GetVideoInfoTag()->m_strPath : item->GetPath();
OnScan(strPath, true);
}
else
@@ -969,7 +970,7 @@ bool CGUIWindowVideoBase::OnPlayMedia(const std::shared_ptr<CFileItem>& pItem,
auto itemCopy = std::make_shared<CFileItem>(*pItem);
- if (pItem->IsVideoDb())
+ if (IsVideoDb(*pItem))
{
itemCopy->SetPath(pItem->GetVideoInfoTag()->m_strFileNameAndPath);
itemCopy->SetProperty("original_listitem_url", pItem->GetPath());
@@ -1082,7 +1083,7 @@ void CGUIWindowVideoBase::LoadPlayList(const std::string& strPlayList,
bool CGUIWindowVideoBase::PlayItem(const std::shared_ptr<CFileItem>& pItem,
const std::string& player)
{
- if (!pItem->m_bIsFolder && pItem->IsVideoDb() && !pItem->Exists())
+ if (!pItem->m_bIsFolder && IsVideoDb(*pItem) && !pItem->Exists())
{
CLog::LogF(LOGDEBUG, "File '{}' for library item '{}' doesn't exist.", pItem->GetDynPath(),
pItem->GetPath());
@@ -1218,9 +1219,8 @@ bool CGUIWindowVideoBase::GetDirectory(const std::string &strDirectory, CFileIte
bool CGUIWindowVideoBase::StackingAvailable(const CFileItemList &items)
{
CURL url(items.GetPath());
- return !(items.IsPlugin() || items.IsAddonsPath() ||
- items.IsRSS() || items.IsInternetStream() ||
- items.IsVideoDb() || url.IsProtocol("playlistvideo"));
+ return !(items.IsPlugin() || items.IsAddonsPath() || items.IsRSS() || items.IsInternetStream() ||
+ IsVideoDb(items) || url.IsProtocol("playlistvideo"));
}
void CGUIWindowVideoBase::GetGroupedItems(CFileItemList &items)
@@ -1267,9 +1267,9 @@ void CGUIWindowVideoBase::GetGroupedItems(CFileItemList &items)
bool CGUIWindowVideoBase::CheckFilterAdvanced(CFileItemList &items) const
{
const std::string& content = items.GetContent();
- if ((items.IsVideoDb() || CanContainFilter(m_strFilterPath)) &&
- (StringUtils::EqualsNoCase(content, "movies") ||
- StringUtils::EqualsNoCase(content, "tvshows") ||
+ if ((IsVideoDb(items) || CanContainFilter(m_strFilterPath)) &&
+ (StringUtils::EqualsNoCase(content, "movies") ||
+ StringUtils::EqualsNoCase(content, "tvshows") ||
StringUtils::EqualsNoCase(content, "episodes") ||
StringUtils::EqualsNoCase(content, "musicvideos")))
return true;
@@ -1343,7 +1343,8 @@ void CGUIWindowVideoBase::OnSearchItemFound(const CFileItem* pSelItem)
Update(strParentPath);
- if (pSelItem->IsVideoDb() && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_FLATTEN))
+ if (IsVideoDb(*pSelItem) && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_MYVIDEOS_FLATTEN))
SetHistoryForPath("");
else
SetHistoryForPath(strParentPath);
@@ -1369,7 +1370,8 @@ void CGUIWindowVideoBase::OnSearchItemFound(const CFileItem* pSelItem)
Update(strPath);
- if (pSelItem->IsVideoDb() && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_FLATTEN))
+ if (IsVideoDb(*pSelItem) && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_MYVIDEOS_FLATTEN))
SetHistoryForPath("");
else
SetHistoryForPath(strPath);
@@ -1378,7 +1380,7 @@ void CGUIWindowVideoBase::OnSearchItemFound(const CFileItem* pSelItem)
{
CFileItemPtr pItem = m_vecItems->Get(i);
CURL url(pItem->GetPath());
- if (pSelItem->IsVideoDb())
+ if (IsVideoDb(*pSelItem))
url.SetOptions("");
if (url.Get() == pSelItem->GetPath())
{
@@ -1520,7 +1522,7 @@ void CGUIWindowVideoBase::UpdateVideoVersionItems()
//! not for example for home screen widgets!
int videoVersionId{-1};
- if (item->IsVideoDb() && item->GetVideoInfoTag()->HasVideoVersions())
+ if (IsVideoDb(*item) && item->GetVideoInfoTag()->HasVideoVersions())
{
if (item->GetProperty("has_resolved_video_asset").asBoolean(false))
{
diff --git a/xbmc/video/windows/GUIWindowVideoNav.cpp b/xbmc/video/windows/GUIWindowVideoNav.cpp
index 86ab1d96eb..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"
@@ -39,6 +40,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoScanner.h"
#include "video/VideoLibraryQueue.h"
#include "video/dialogs/GUIDialogVideoInfo.h"
@@ -49,6 +51,7 @@
using namespace XFILE;
using namespace VIDEODATABASEDIRECTORY;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
#define CONTROL_BTNVIEWASICONS 2
#define CONTROL_BTNSORTBY 3
@@ -152,7 +155,7 @@ bool CGUIWindowVideoNav::OnMessage(CGUIMessage& message)
// We are here if the item is filtered out in the nav window
const std::string& path = message.GetStringParam(0);
CFileItem item(path, URIUtils::HasSlashAtEnd(path));
- if (item.IsVideoDb())
+ if (IsVideoDb(item))
{
*(item.GetVideoInfoTag()) = XFILE::CVideoDatabaseFile::GetVideoTag(CURL(item.GetPath()));
if (!item.GetVideoInfoTag()->IsEmpty())
@@ -242,7 +245,7 @@ bool CGUIWindowVideoNav::OnMessage(CGUIMessage& message)
SelectFirstUnwatchedItem CGUIWindowVideoNav::GetSettingSelectFirstUnwatchedItem()
{
- if (m_vecItems->IsVideoDb())
+ if (IsVideoDb(*m_vecItems))
{
NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath());
@@ -358,7 +361,7 @@ bool CGUIWindowVideoNav::GetDirectory(const std::string &strDirectory, CFileItem
bool bResult = CGUIWindowVideoBase::GetDirectory(strDirectory, items);
if (bResult)
{
- if (items.IsVideoDb())
+ if (IsVideoDb(items))
{
XFILE::CVideoDatabaseDirectory dir;
CQueryParams params;
@@ -546,7 +549,7 @@ void CGUIWindowVideoNav::UpdateButtons()
else if (m_vecItems->IsPath("sources://video/"))
strLabel = g_localizeStrings.Get(744);
// everything else is from a videodb:// path
- else if (m_vecItems->IsVideoDb())
+ else if (IsVideoDb(*m_vecItems))
{
CVideoDatabaseDirectory dir;
dir.GetLabel(m_vecItems->GetPath(), strLabel);
@@ -671,7 +674,7 @@ void CGUIWindowVideoNav::OnDeleteItem(const CFileItemPtr& pItem)
if (m_vecItems->IsParentFolder())
return;
- if (!m_vecItems->IsVideoDb() && !pItem->IsVideoDb())
+ if (!IsVideoDb(*m_vecItems) && !IsVideoDb(*pItem))
{
if (!pItem->IsPath("newsmartplaylist://video") && !pItem->IsPath("special://videoplaylists/") &&
!pItem->IsPath("sources://video/") && !URIUtils::IsProtocol(pItem->GetPath(), "newtag"))
@@ -798,7 +801,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
// can we update the database?
if (profileManager->GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
{
- if (!CVideoLibraryQueue::GetInstance().IsScanningLibrary() && item->IsVideoDb() &&
+ if (!CVideoLibraryQueue::GetInstance().IsScanningLibrary() && IsVideoDb(*item) &&
item->HasVideoInfoTag() &&
(item->GetVideoInfoTag()->m_type == MediaTypeMovie || // movies
item->GetVideoInfoTag()->m_type == MediaTypeTvShow || // tvshows
@@ -824,7 +827,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
}
}
- if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
+ if (!IsVideoDb(*m_vecItems) && !m_vecItems->IsVirtualDirectoryRoot())
{ // non-video db items, file operations are allowed
if ((CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_ALLOWFILEDELETION) &&
CUtil::SupportsWriteFileOperations(item->GetPath())) ||
@@ -835,7 +838,9 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
buttons.Add(CONTEXT_BUTTON_RENAME, 118);
}
// add "Set/Change content" to folders
- if (item->m_bIsFolder && !item->IsVideoDb() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath()))
+ if (item->m_bIsFolder && !IsVideoDb(*item) && !item->IsPlayList() &&
+ !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() &&
+ !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath()))
{
if (info && info->Content() != CONTENT_NONE)
buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
@@ -1079,7 +1084,7 @@ bool CGUIWindowVideoNav::ApplyWatchedFilter(CFileItemList &items)
|| node == NODE_TYPE_RECENTLY_ADDED_MOVIES
|| node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
filterWatched = true;
- if (!items.IsVideoDb())
+ if (!IsVideoDb(items))
filterWatched = true;
if (items.GetContent() == "tvshows" &&
(items.IsSmartPlayList() || items.IsLibraryFolder()))
diff --git a/xbmc/video/windows/GUIWindowVideoPlaylist.cpp b/xbmc/video/windows/GUIWindowVideoPlaylist.cpp
index 3569a0c5ea..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"
@@ -30,6 +31,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/guilib/VideoPlayActionProcessor.h"
#define CONTROL_BTNVIEWASICONS 2
@@ -46,6 +48,7 @@
#define CONTROL_BTNPREVIOUS 25
#define CONTROL_BTNREPEAT 26
+using namespace KODI::VIDEO;
using namespace VIDEO::GUILIB;
CGUIWindowVideoPlaylist::CGUIWindowVideoPlaylist()
@@ -63,7 +66,7 @@ void CGUIWindowVideoPlaylist::OnPrepareFileItems(CFileItemList& items)
if (items.IsEmpty())
return;
- if (!items.IsVideoDb() && !items.IsVirtualDirectoryRoot())
+ if (!IsVideoDb(items) && !items.IsVirtualDirectoryRoot())
{ // load info from the database
std::string label;
if (items.GetLabel().empty() &&
diff --git a/xbmc/video/windows/VideoFileItemListModifier.cpp b/xbmc/video/windows/VideoFileItemListModifier.cpp
index b17a71db87..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"
@@ -17,14 +18,16 @@
#include "settings/SettingsComponent.h"
#include "video/VideoDatabase.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include <memory>
+using namespace KODI::VIDEO;
using namespace XFILE::VIDEODATABASEDIRECTORY;
bool CVideoFileItemListModifier::CanModify(const CFileItemList &items) const
{
- if (items.IsVideoDb())
+ if (IsVideoDb(items))
return true;
return false;
@@ -40,7 +43,7 @@ bool CVideoFileItemListModifier::Modify(CFileItemList &items) const
// depending on the child node
void CVideoFileItemListModifier::AddQueuingFolder(CFileItemList& items)
{
- if (!items.IsVideoDb())
+ if (!IsVideoDb(items))
return;
auto directoryNode = CDirectoryNode::ParseURL(items.GetPath());
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/windowing/osx/OpenGL/OSXGLView.h b/xbmc/windowing/osx/OpenGL/OSXGLView.h
index 54a85a232f..016e102e78 100644
--- a/xbmc/windowing/osx/OpenGL/OSXGLView.h
+++ b/xbmc/windowing/osx/OpenGL/OSXGLView.h
@@ -16,12 +16,6 @@
- (CGLContextObj)getGLContextObj;
/**
- * @brief Application renders out of the NSOpenGLView drawRect (on a different thread). Hence the current
- * NSOpenGLContext needs to be make current so that the view on the context is valid for rendering.
- * This should be done whenever gl calls are about to be done.
- */
-- (void)NotifyContext;
-/**
* @brief Update the current OpenGL context (view is set before updating)
*/
- (void)Update;
@@ -30,9 +24,4 @@
*/
- (void)FlushBuffer;
-/**
- * @brief Specifies if the glContext is currently owned by the view
- */
-@property(atomic, assign) BOOL glContextOwned;
-
@end
diff --git a/xbmc/windowing/osx/OpenGL/OSXGLView.mm b/xbmc/windowing/osx/OpenGL/OSXGLView.mm
index 195ea0d889..857174838a 100644
--- a/xbmc/windowing/osx/OpenGL/OSXGLView.mm
+++ b/xbmc/windowing/osx/OpenGL/OSXGLView.mm
@@ -20,8 +20,6 @@
NSTrackingArea* m_trackingArea;
}
-@synthesize glContextOwned;
-
- (void)SendInputEvent:(NSEvent*)nsEvent
{
CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
@@ -88,14 +86,6 @@
- (void)drawRect:(NSRect)rect
{
- // whenever the view/window is resized the glContext is made current to the main (rendering) thread.
- // Since kodi does its rendering on the application main thread (not the macOS rendering thread), we
- // need to store this so that on a subsquent frame render we get the ownership of the gl context again.
- // doing this blindly without any sort of control may stall the main thread and lead to low GUI fps
- // since the glContext ownership needs to be obtained from the rendering thread (diverged from the actual
- // thread doing the rendering calls).
- [self setGlContextOwned:TRUE];
-
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self setOpenGLContext:m_glcontext];
@@ -215,17 +205,8 @@
- (void)Update
{
assert(m_glcontext);
- [self NotifyContext];
- [m_glcontext update];
-}
-
-- (void)NotifyContext
-{
- assert(m_glcontext);
- // signals/notifies the context that this view is current (required if we render out of DrawRect)
- // ownership of the context is transferred to the callee thread
[m_glcontext makeCurrentContext];
- [self setGlContextOwned:FALSE];
+ [m_glcontext update];
}
- (void)FlushBuffer
diff --git a/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm b/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
index 5bfb6b0d22..4f50a49dbc 100644
--- a/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
+++ b/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
@@ -22,6 +22,8 @@
@implementation XBMCWindowControllerMacOS
+bool m_inFullscreenTransition = false;
+
- (nullable instancetype)initWithTitle:(NSString*)title defaultSize:(NSSize)size
{
auto frame = NSMakeRect(0, 0, size.width, size.height);
@@ -77,6 +79,30 @@
}
}
+- (void)windowWillStartLiveResize:(NSNotification*)notification
+{
+ if (m_inFullscreenTransition)
+ return;
+
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ {
+ appPort->SetRenderGUI(false);
+ }
+}
+
+- (void)windowDidEndLiveResize:(NSNotification*)notification
+{
+ if (m_inFullscreenTransition)
+ return;
+
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ {
+ appPort->SetRenderGUI(true);
+ }
+}
+
- (void)windowDidMiniaturize:(NSNotification*)aNotification
{
g_application.m_AppFocused = false;
@@ -170,8 +196,14 @@
return frameSize;
}
+- (void)windowWillExitFullScreen:(NSNotification*)notification
+{
+ m_inFullscreenTransition = true;
+}
+
- (void)windowWillEnterFullScreen:(NSNotification*)pNotification
{
+ m_inFullscreenTransition = true;
CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
if (!winSystem)
return;
@@ -209,6 +241,7 @@
- (void)windowDidExitFullScreen:(NSNotification*)pNotification
{
+ m_inFullscreenTransition = false;
auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
if (!winSystem)
return;
@@ -235,6 +268,7 @@
- (void)windowDidEnterFullScreen:(NSNotification*)notification
{
+ m_inFullscreenTransition = false;
auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
if (!winSystem)
return;
diff --git a/xbmc/windowing/osx/WinSystemOSX.h b/xbmc/windowing/osx/WinSystemOSX.h
index c431d70cd9..899e52486b 100644
--- a/xbmc/windowing/osx/WinSystemOSX.h
+++ b/xbmc/windowing/osx/WinSystemOSX.h
@@ -71,7 +71,6 @@ public:
void MoveToScreen(unsigned int screenIdx) override;
void OnMove(int x, int y) override;
void OnChangeScreen(unsigned int screenIdx) override;
- CGraphicContext& GetGfxContext() const override;
bool HasValidResolution() const;
std::string GetClipboardText() override;
diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm
index 04a0670a17..007fc14be3 100644
--- a/xbmc/windowing/osx/WinSystemOSX.mm
+++ b/xbmc/windowing/osx/WinSystemOSX.mm
@@ -1304,18 +1304,6 @@ CGLContextObj CWinSystemOSX::GetCGLContextObj()
return cglcontex;
}
-CGraphicContext& CWinSystemOSX::GetGfxContext() const
-{
- if (m_glView && [m_glView glContextOwned])
- {
- dispatch_sync(dispatch_get_main_queue(), ^{
- [m_glView NotifyContext];
- });
- }
-
- return CWinSystemBase::GetGfxContext();
-}
-
bool CWinSystemOSX::FlushBuffer()
{
if (m_appWindow)
diff --git a/xbmc/windowing/win10/WinSystemWin10.cpp b/xbmc/windowing/win10/WinSystemWin10.cpp
index ccdbc395f3..1461d797b0 100644
--- a/xbmc/windowing/win10/WinSystemWin10.cpp
+++ b/xbmc/windowing/win10/WinSystemWin10.cpp
@@ -692,7 +692,14 @@ float CWinSystemWin10::GetGuiSdrPeakLuminance() const
*/
bool CWinSystemWin10::HasSystemSdrPeakLuminance()
{
- return CWIN32Util::GetSystemSdrWhiteLevel(std::wstring(), nullptr);
+ if (m_uiThreadId == GetCurrentThreadId())
+ {
+ const bool hasSystemSdrPeakLum = CWIN32Util::GetSystemSdrWhiteLevel(std::wstring(), nullptr);
+ m_cachedHasSystemSdrPeakLum = hasSystemSdrPeakLum;
+ return hasSystemSdrPeakLum;
+ }
+
+ return m_cachedHasSystemSdrPeakLum;
}
/*!
diff --git a/xbmc/windowing/win10/WinSystemWin10.h b/xbmc/windowing/win10/WinSystemWin10.h
index c53fd01872..6b5be4bb4e 100644
--- a/xbmc/windowing/win10/WinSystemWin10.h
+++ b/xbmc/windowing/win10/WinSystemWin10.h
@@ -156,6 +156,10 @@ protected:
bool m_validSystemSdrPeakLuminance{false};
float m_systemSdrPeakLuminance{.0f};
+
+ DWORD m_uiThreadId{0};
+ HDR_STATUS m_cachedHdrStatus{HDR_STATUS::HDR_UNSUPPORTED};
+ bool m_cachedHasSystemSdrPeakLum{false};
};
#pragma pack(pop)
diff --git a/xbmc/windowing/win10/WinSystemWin10DX.cpp b/xbmc/windowing/win10/WinSystemWin10DX.cpp
index 1101b1a7ef..55167ff386 100644
--- a/xbmc/windowing/win10/WinSystemWin10DX.cpp
+++ b/xbmc/windowing/win10/WinSystemWin10DX.cpp
@@ -61,6 +61,14 @@ bool CWinSystemWin10DX::CreateNewWindow(const std::string& name, bool fullScreen
m_deviceResources = DX::DeviceResources::Get();
m_deviceResources->SetWindow(m_coreWindow);
+ // saves threadId of current thread (UI thread)
+ m_uiThreadId = GetCurrentThreadId();
+
+ // calls these methods to make sure cached values are properly initialized
+ // and can be used later when called from other thread
+ IsHDRDisplay();
+ HasSystemSdrPeakLuminance();
+
if (CWinSystemWin10::CreateNewWindow(name, fullScreen, res) && m_deviceResources->HasValidDevice())
{
CGenericTouchInputHandler::GetInstance().RegisterHandler(&CGenericTouchActionHandler::GetInstance());
@@ -166,7 +174,14 @@ void CWinSystemWin10DX::InitHooks(IDXGIOutput* pOutput)
bool CWinSystemWin10DX::IsHDRDisplay()
{
- return (CWIN32Util::GetWindowsHDRStatus() != HDR_STATUS::HDR_UNSUPPORTED);
+ if (m_uiThreadId == GetCurrentThreadId())
+ {
+ const HDR_STATUS hdrStatus = CWIN32Util::GetWindowsHDRStatus();
+ m_cachedHdrStatus = hdrStatus;
+ return (hdrStatus != HDR_STATUS::HDR_UNSUPPORTED);
+ }
+
+ return (m_cachedHdrStatus != HDR_STATUS::HDR_UNSUPPORTED);
}
HDR_STATUS CWinSystemWin10DX::GetOSHDRStatus()
diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp
index 5dacf417a1..aab1d37e0c 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"
@@ -59,6 +60,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "view/GUIViewState.h"
#include <inttypes.h>
@@ -78,6 +80,7 @@
using namespace ADDON;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
using namespace std::chrono_literals;
namespace
@@ -1550,7 +1553,8 @@ bool CGUIMediaWindow::OnPlayAndQueueMedia(const CFileItemPtr& item, const std::s
if (nItem->m_bIsFolder)
continue;
- if (!nItem->IsZIP() && !nItem->IsRAR() && (!nItem->IsDVDFile() || (URIUtils::GetFileName(nItem->GetDynPath()) == mainDVD)))
+ if (!nItem->IsZIP() && !nItem->IsRAR() &&
+ (!IsDVDFile(*nItem) || (URIUtils::GetFileName(nItem->GetDynPath()) == mainDVD)))
CServiceBroker::GetPlaylistPlayer().Add(playlistId, nItem);
if (item->IsSamePath(nItem.get()))
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"