diff options
314 files changed, 4738 insertions, 2388 deletions
diff --git a/.gitignore b/.gitignore index 5afd7ff438..b51cbca70a 100644 --- a/.gitignore +++ b/.gitignore @@ -145,6 +145,9 @@ config.log /lib/addons/library.xbmc.codec/project/VS2010Express/Debug /lib/addons/library.xbmc.pvr/project/VS2010Express/Release /lib/addons/library.xbmc.pvr/project/VS2010Express/Debug +/lib/addons/library.kodi.audioengine/Makefile +/lib/addons/library.kodi.audioengine/project/VS2010Express/Release/ +/lib/addons/library.kodi.audioengine/project/VS2010Express/Debug/ # /lib/cpluff/ /lib/cpluff/ABOUT-NLS @@ -827,6 +830,8 @@ xbmc/main/posix/Makefile /addons/library.kodi.guilib/libKODI_guilib.lib /addons/library.xbmc.pvr/libXBMC_pvr.dll /addons/library.xbmc.pvr/libXBMC_pvr.lib +/addons/library.kodi.audioengine/libKODI_audioengine.dll +/addons/library.kodi.audioengine/libKODI_audioengine.lib /pvr-addons /adsp-addons diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 4a6268b53c..87d4c58b3d 100644 --- a/Kodi.xcodeproj/project.pbxproj +++ b/Kodi.xcodeproj/project.pbxproj @@ -327,6 +327,9 @@ 7C1A85661520522500C63311 /* TextureCacheJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1A85631520522500C63311 /* TextureCacheJob.cpp */; }; 7C1D682915A7D2FD00658B65 /* DatabaseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1D682715A7D2FD00658B65 /* DatabaseManager.cpp */; }; 7C1F6EBB13ECCFA7001726AB /* LibraryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1F6EB913ECCFA7001726AB /* LibraryDirectory.cpp */; }; + 7C226E3E1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C226E3C1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp */; }; + 7C226E3F1BA5F61D00185CE0 /* AddonCallbacksAudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C226E3C1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp */; }; + 7C226E401BA5F61D00185CE0 /* AddonCallbacksAudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C226E3C1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp */; }; 7C26126C182068660086E04D /* SettingsOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C26126A182068660086E04D /* SettingsOperations.cpp */; }; 7C26126D182068660086E04D /* SettingsOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C26126A182068660086E04D /* SettingsOperations.cpp */; }; 7C26126E182068660086E04D /* SettingsOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C26126A182068660086E04D /* SettingsOperations.cpp */; }; @@ -1172,8 +1175,6 @@ DFEF0BC1180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEF0BBF180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp */; }; DFEF0BC2180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEF0BBF180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp */; }; DFEF0BC3180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEF0BBF180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp */; }; - DFF0EB54175280D1002DA3A4 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F56C8CE6131F5DC6000AD0F6 /* libz.dylib */; }; - DFF0EB55175280E5002DA3A4 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F56C8CF2131F5DFD000AD0F6 /* libiconv.dylib */; }; DFF0EBB3175281CE002DA3A4 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49910EC174E54D200741B6D /* AudioToolbox.framework */; }; DFF0EBB4175281D6002DA3A4 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49910F0174E54EC00741B6D /* CFNetwork.framework */; }; DFF0EBB6175281E0002DA3A4 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49910EA174E54C900741B6D /* CoreAudio.framework */; }; @@ -1813,7 +1814,6 @@ DFF0F3BB17528350002DA3A4 /* AliasShortcutUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A9D3081097C9370050490F /* AliasShortcutUtils.cpp */; }; DFF0F3BC17528350002DA3A4 /* Archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E250D25F9FD00618676 /* Archive.cpp */; }; DFF0F3BD17528350002DA3A4 /* AsyncFileCopy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5FDF51C0E7218950005B0A6 /* AsyncFileCopy.cpp */; }; - DFF0F3BE17528350002DA3A4 /* AutoPtrHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */; }; DFF0F3BF17528350002DA3A4 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769A151BAEDA00B5B63B /* Base64.cpp */; }; DFF0F3C017528350002DA3A4 /* BitstreamConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56353BD16E9BB3500D21BAD /* BitstreamConverter.cpp */; }; DFF0F3C117528350002DA3A4 /* BitstreamStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E270D25F9FD00618676 /* BitstreamStats.cpp */; }; @@ -2347,8 +2347,6 @@ E49910F1174E54ED00741B6D /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49910F0174E54EC00741B6D /* CFNetwork.framework */; }; E49910F3174E54FB00741B6D /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49910F2174E54FB00741B6D /* AVFoundation.framework */; }; E49910F5174E550200741B6D /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49910F4174E550200741B6D /* MediaPlayer.framework */; }; - E49910F8174E561500741B6D /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F56C8CE6131F5DC6000AD0F6 /* libz.dylib */; }; - E49910F9174E561D00741B6D /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F56C8CF2131F5DFD000AD0F6 /* libiconv.dylib */; }; E499114F174E5CC300741B6D /* archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1CE60D25F9FC00618676 /* archive.cpp */; settings = {COMPILER_FLAGS = "-DSILENT"; }; }; E4991150174E5CC300741B6D /* arcread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1CE80D25F9FC00618676 /* arcread.cpp */; settings = {COMPILER_FLAGS = "-DSILENT"; }; }; E4991151174E5CC300741B6D /* cmddata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1CEA0D25F9FC00618676 /* cmddata.cpp */; settings = {COMPILER_FLAGS = "-DSILENT"; }; }; @@ -2975,7 +2973,6 @@ E499143F174E605900741B6D /* AliasShortcutUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A9D3081097C9370050490F /* AliasShortcutUtils.cpp */; }; E4991440174E605900741B6D /* Archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E250D25F9FD00618676 /* Archive.cpp */; }; E4991441174E605900741B6D /* AsyncFileCopy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5FDF51C0E7218950005B0A6 /* AsyncFileCopy.cpp */; }; - E4991442174E605900741B6D /* AutoPtrHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */; }; E4991443174E605900741B6D /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769A151BAEDA00B5B63B /* Base64.cpp */; }; E4991444174E605900741B6D /* BitstreamConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56353BD16E9BB3500D21BAD /* BitstreamConverter.cpp */; }; E4991445174E605900741B6D /* BitstreamStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E270D25F9FD00618676 /* BitstreamStats.cpp */; }; @@ -3174,7 +3171,6 @@ F52CC5F01713AAA200113454 /* DirectoryNodeGrouped.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52CC5EE1713AAA200113454 /* DirectoryNodeGrouped.cpp */; }; F52CC6AA1713BD2B00113454 /* DirectoryNodeGrouped.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52CC6A81713BD2B00113454 /* DirectoryNodeGrouped.cpp */; }; F5364D34155B3B270016D00B /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5364D33155B3B270016D00B /* CoreVideo.framework */; }; - F5364D55155B3C7B0016D00B /* libm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F5364D54155B3C7B0016D00B /* libm.dylib */; }; F5364E05155B3CAF0016D00B /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5364E04155B3CAF0016D00B /* IOSurface.framework */; }; F548786D0FE060FF00E506FD /* DVDSubtitleParserMPL2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F548786C0FE060FF00E506FD /* DVDSubtitleParserMPL2.cpp */; }; F5487B4C0FE6F02700E506FD /* StreamDetails.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5487B4B0FE6F02700E506FD /* StreamDetails.cpp */; }; @@ -3205,8 +3201,6 @@ F56353BF16E9BB3500D21BAD /* BitstreamConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56353BD16E9BB3500D21BAD /* BitstreamConverter.cpp */; }; F56579AF13060D1E0085ED7F /* RenderCapture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56579AD13060D1E0085ED7F /* RenderCapture.cpp */; }; F56A084B0F4A18FB003F9F87 /* karaokewindowbackground.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56A084A0F4A18FB003F9F87 /* karaokewindowbackground.cpp */; }; - F56C8CE7131F5DC6000AD0F6 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F56C8CE6131F5DC6000AD0F6 /* libz.dylib */; }; - F56C8CF3131F5DFD000AD0F6 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F56C8CF2131F5DFD000AD0F6 /* libiconv.dylib */; }; F57A1D1E1329B15300498CC7 /* AutoPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = F57A1D1D1329B15300498CC7 /* AutoPool.mm */; }; F57B6F801071B8B500079ACB /* JobManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F57B6F7E1071B8B500079ACB /* JobManager.cpp */; }; F584E12E0F257C5100DB26A5 /* HTTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F584E12D0F257C5100DB26A5 /* HTTPDirectory.cpp */; }; @@ -3245,7 +3239,6 @@ F5BD02F6148D3A7E001B5583 /* CryptThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BD02F4148D3A7E001B5583 /* CryptThreading.cpp */; }; F5BDB80C120202F400F0B710 /* DVDSubtitleTagSami.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB80B120202F400F0B710 /* DVDSubtitleTagSami.cpp */; }; F5BDB81A1202032400F0B710 /* DVDSubtitleTagMicroDVD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB8191202032400F0B710 /* DVDSubtitleTagMicroDVD.cpp */; }; - F5BDB820120203C200F0B710 /* AutoPtrHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */; }; F5CC228B1814F7E9006B5E91 /* AESinkDARWINOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22891814F7E9006B5E91 /* AESinkDARWINOSX.cpp */; }; F5CC228E1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */; }; F5CC228F1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */; }; @@ -3710,6 +3703,7 @@ 3994426A1A8DD920006C39E9 /* VideoLibraryScanningJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoLibraryScanningJob.h; sourceTree = "<group>"; }; 3994427D1A8DD96F006C39E9 /* VideoLibraryQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoLibraryQueue.cpp; sourceTree = "<group>"; }; 3994427E1A8DD96F006C39E9 /* VideoLibraryQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoLibraryQueue.h; sourceTree = "<group>"; }; + 399B860B1BA49A230017F660 /* ScopeGuard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeGuard.h; sourceTree = "<group>"; }; 39B4F36E1B96F845009B2D88 /* RepositoryUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RepositoryUpdater.cpp; sourceTree = "<group>"; }; 39B4F36F1B96F845009B2D88 /* RepositoryUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RepositoryUpdater.h; sourceTree = "<group>"; }; 39BD2AD61B845D40004A5A15 /* DialogHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DialogHelper.h; path = helpers/DialogHelper.h; sourceTree = "<group>"; }; @@ -3804,6 +3798,8 @@ 7C1D682815A7D2FD00658B65 /* DatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseManager.h; sourceTree = "<group>"; }; 7C1F6EB913ECCFA7001726AB /* LibraryDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LibraryDirectory.cpp; sourceTree = "<group>"; }; 7C1F6EBA13ECCFA7001726AB /* LibraryDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LibraryDirectory.h; sourceTree = "<group>"; }; + 7C226E3C1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonCallbacksAudioEngine.cpp; sourceTree = "<group>"; }; + 7C226E3D1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonCallbacksAudioEngine.h; sourceTree = "<group>"; }; 7C26126A182068660086E04D /* SettingsOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SettingsOperations.cpp; sourceTree = "<group>"; }; 7C26126B182068660086E04D /* SettingsOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsOperations.h; sourceTree = "<group>"; }; 7C26126F1825B6340086E04D /* DatabaseQuery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseQuery.cpp; sourceTree = "<group>"; }; @@ -5728,7 +5724,6 @@ F52CC6A81713BD2B00113454 /* DirectoryNodeGrouped.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryNodeGrouped.cpp; sourceTree = "<group>"; }; F52CC6A91713BD2B00113454 /* DirectoryNodeGrouped.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryNodeGrouped.h; sourceTree = "<group>"; }; F5364D33155B3B270016D00B /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = /System/Library/Frameworks/CoreVideo.framework; sourceTree = "<absolute>"; }; - F5364D54155B3C7B0016D00B /* libm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libm.dylib; path = /usr/lib/libm.dylib; sourceTree = "<absolute>"; }; F5364E04155B3CAF0016D00B /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = /System/Library/Frameworks/IOSurface.framework; sourceTree = "<absolute>"; }; F548786B0FE060FF00E506FD /* DVDSubtitleParserMPL2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDSubtitleParserMPL2.h; sourceTree = "<group>"; }; F548786C0FE060FF00E506FD /* DVDSubtitleParserMPL2.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = DVDSubtitleParserMPL2.cpp; sourceTree = "<group>"; }; @@ -5783,8 +5778,6 @@ F56579AE13060D1E0085ED7F /* RenderCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderCapture.h; sourceTree = "<group>"; }; F56A08490F4A18FB003F9F87 /* karaokewindowbackground.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = karaokewindowbackground.h; sourceTree = "<group>"; }; F56A084A0F4A18FB003F9F87 /* karaokewindowbackground.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = karaokewindowbackground.cpp; sourceTree = "<group>"; }; - F56C8CE6131F5DC6000AD0F6 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; - F56C8CF2131F5DFD000AD0F6 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; }; F57A1D1C1329B15300498CC7 /* AutoPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoPool.h; sourceTree = "<group>"; }; F57A1D1D1329B15300498CC7 /* AutoPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoPool.mm; sourceTree = "<group>"; }; F57B6F7E1071B8B500079ACB /* JobManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JobManager.cpp; sourceTree = "<group>"; }; @@ -5855,8 +5848,6 @@ F5BDB80B120202F400F0B710 /* DVDSubtitleTagSami.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDSubtitleTagSami.cpp; sourceTree = "<group>"; }; F5BDB8181202032400F0B710 /* DVDSubtitleTagMicroDVD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDSubtitleTagMicroDVD.h; sourceTree = "<group>"; }; F5BDB8191202032400F0B710 /* DVDSubtitleTagMicroDVD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDSubtitleTagMicroDVD.cpp; sourceTree = "<group>"; }; - F5BDB81E120203C200F0B710 /* AutoPtrHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoPtrHandle.h; sourceTree = "<group>"; }; - F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AutoPtrHandle.cpp; sourceTree = "<group>"; }; F5CC22891814F7E9006B5E91 /* AESinkDARWINOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AESinkDARWINOSX.cpp; path = Sinks/AESinkDARWINOSX.cpp; sourceTree = "<group>"; }; F5CC228A1814F7E9006B5E91 /* AESinkDARWINOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AESinkDARWINOSX.h; path = Sinks/AESinkDARWINOSX.h; sourceTree = "<group>"; }; F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AESinkDARWINIOS.cpp; path = Sinks/AESinkDARWINIOS.cpp; sourceTree = "<group>"; }; @@ -5955,9 +5946,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F56C8CE7131F5DC6000AD0F6 /* libz.dylib in Frameworks */, - F5364D55155B3C7B0016D00B /* libm.dylib in Frameworks */, - F56C8CF3131F5DFD000AD0F6 /* libiconv.dylib in Frameworks */, F5ED9BFB155EC77400842059 /* ApplicationServices.framework in Frameworks */, E38E23930D2626E600618676 /* AudioUnit.framework in Frameworks */, E38E23920D2626E600618676 /* AudioToolbox.framework in Frameworks */, @@ -5980,8 +5968,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DFF0EB54175280D1002DA3A4 /* libz.dylib in Frameworks */, - DFF0EB55175280E5002DA3A4 /* libiconv.dylib in Frameworks */, DFF0EBB3175281CE002DA3A4 /* AudioToolbox.framework in Frameworks */, DFF0EBB4175281D6002DA3A4 /* CFNetwork.framework in Frameworks */, DFF0EBB6175281E0002DA3A4 /* CoreAudio.framework in Frameworks */, @@ -6012,8 +5998,6 @@ E499108C174D0D2600741B6D /* UIKit.framework in Frameworks */, E499108E174D0D2600741B6D /* Foundation.framework in Frameworks */, E4991090174D0D2600741B6D /* CoreGraphics.framework in Frameworks */, - E49910F8174E561500741B6D /* libz.dylib in Frameworks */, - E49910F9174E561D00741B6D /* libiconv.dylib in Frameworks */, DFF0EBB7175281E1002DA3A4 /* CoreAudio.framework in Frameworks */, DFF0EC8C17528283002DA3A4 /* VideoToolbox.framework in Frameworks */, ); @@ -6029,7 +6013,6 @@ 08FB779DFE84155DC02AAC07 /* System Libs and Frameworks */, E49910C2174E2CDE00741B6D /* Configurations */, E47252BE175115F9001C1AAA /* Support */, - E499108A174D0D2600741B6D /* Frameworks */, 19C28FBDFE9D53C911CA2CBB /* Products */, ); indentWidth = 2; @@ -6054,9 +6037,6 @@ DFF0EB7E17528112002DA3A4 /* ATV2 */, E49910F6174E55D400741B6D /* iOS */, E49910F7174E55E100741B6D /* OSX */, - F56C8CE6131F5DC6000AD0F6 /* libz.dylib */, - F5364D54155B3C7B0016D00B /* libm.dylib */, - F56C8CF2131F5DFD000AD0F6 /* libiconv.dylib */, ); name = "System Libs and Frameworks"; sourceTree = "<group>"; @@ -6064,6 +6044,8 @@ 18B49FF01152BEEB001AF8A6 /* addons */ = { isa = PBXGroup; children = ( + 7C226E3C1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp */, + 7C226E3D1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.h */, 7C973CE31B50378E0002A874 /* AddonCallbacksAudioDSP.cpp */, 7C973CE41B50378E0002A874 /* AddonCallbacksAudioDSP.h */, 18B49FF11152BFA5001AF8A6 /* Addon.cpp */, @@ -9497,8 +9479,6 @@ F5FDF51B0E7218950005B0A6 /* AsyncFileCopy.h */, 7C908892196358A8003D0619 /* auto_buffer.cpp */, 7C908893196358A8003D0619 /* auto_buffer.h */, - F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */, - F5BDB81E120203C200F0B710 /* AutoPtrHandle.h */, DF52769A151BAEDA00B5B63B /* Base64.cpp */, DF52769B151BAEDA00B5B63B /* Base64.h */, F56353BD16E9BB3500D21BAD /* BitstreamConverter.cpp */, @@ -9597,6 +9577,7 @@ E38E1E760D25F9FD00618676 /* RssReader.h */, 7C525DF4195E2D8100BE3482 /* SaveFileStateJob.cpp */, 7C1A495B15A96918004AF4A4 /* SaveFileStateJob.h */, + 399B860B1BA49A230017F660 /* ScopeGuard.h */, E38E1E770D25F9FD00618676 /* ScraperParser.cpp */, E38E1E780D25F9FD00618676 /* ScraperParser.h */, E36C29E70DA72486001F0C9D /* ScraperUrl.cpp */, @@ -9692,16 +9673,6 @@ path = tools/darwin/Support; sourceTree = "<group>"; }; - E499108A174D0D2600741B6D /* Frameworks */ = { - isa = PBXGroup; - children = ( - E499108B174D0D2600741B6D /* UIKit.framework */, - E499108D174D0D2600741B6D /* Foundation.framework */, - E499108F174D0D2600741B6D /* CoreGraphics.framework */, - ); - name = Frameworks; - sourceTree = "<group>"; - }; E49910A6174D0E2A00741B6D /* iOS */ = { isa = PBXGroup; children = ( @@ -9759,6 +9730,9 @@ E49910EE174E54E400741B6D /* ImageIO.framework */, E49910F4174E550200741B6D /* MediaPlayer.framework */, E49910E4174E54A100741B6D /* OpenGLES.framework */, + E499108B174D0D2600741B6D /* UIKit.framework */, + E499108D174D0D2600741B6D /* Foundation.framework */, + E499108F174D0D2600741B6D /* CoreGraphics.framework */, E49910E2174E549400741B6D /* QuartzCore.framework */, ); name = iOS; @@ -10128,7 +10102,6 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; }; buildConfigurationList = 1DEB924B08733DCA0010E9CD /* Build configuration list for PBXProject "Kodi" */; compatibilityVersion = "Xcode 3.2"; @@ -10901,7 +10874,6 @@ F58E293911FFC103006F4D46 /* DVDInputStreamBluray.cpp in Sources */, F5BDB80C120202F400F0B710 /* DVDSubtitleTagSami.cpp in Sources */, F5BDB81A1202032400F0B710 /* DVDSubtitleTagMicroDVD.cpp in Sources */, - F5BDB820120203C200F0B710 /* AutoPtrHandle.cpp in Sources */, 7CF1FB0C123B1AF000B2CBCB /* Variant.cpp in Sources */, C8D0B2AF1265A9A800F0C0AC /* SystemGlobals.cpp in Sources */, 7CBEBB8412912BA400431822 /* fstrcmp.c in Sources */, @@ -11293,6 +11265,7 @@ F56352AA16E5402100D21BAD /* GUIDialogContentSettings.cpp in Sources */, F56352BB16E5403400D21BAD /* GUIWindowSettings.cpp in Sources */, F56352BC16E5403400D21BAD /* GUIWindowSettingsCategory.cpp in Sources */, + 7C226E3E1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp in Sources */, F56352BE16E5403400D21BAD /* GUIWindowSettingsScreenCalibration.cpp in Sources */, F56352BF16E5403400D21BAD /* GUIWindowTestPattern.cpp in Sources */, F56352C816E5436900D21BAD /* AppParamParser.cpp in Sources */, @@ -11874,6 +11847,7 @@ DF0E4AD11AD5984600A75430 /* PVRRadioRDSInfoTag.cpp in Sources */, DFF0F26D17528350002DA3A4 /* ZeroconfDirectory.cpp in Sources */, DFF0F26E17528350002DA3A4 /* ZipDirectory.cpp in Sources */, + 7C226E401BA5F61D00185CE0 /* AddonCallbacksAudioEngine.cpp in Sources */, DFF0F26F17528350002DA3A4 /* ZipFile.cpp in Sources */, DFF0F27017528350002DA3A4 /* ZipManager.cpp in Sources */, DFF0F27217528350002DA3A4 /* cximage.cpp in Sources */, @@ -12221,7 +12195,6 @@ DFF0F3BB17528350002DA3A4 /* AliasShortcutUtils.cpp in Sources */, DFF0F3BC17528350002DA3A4 /* Archive.cpp in Sources */, DFF0F3BD17528350002DA3A4 /* AsyncFileCopy.cpp in Sources */, - DFF0F3BE17528350002DA3A4 /* AutoPtrHandle.cpp in Sources */, DFF0F3BF17528350002DA3A4 /* Base64.cpp in Sources */, DFF0F3C017528350002DA3A4 /* BitstreamConverter.cpp in Sources */, DFF0F3C117528350002DA3A4 /* BitstreamStats.cpp in Sources */, @@ -13297,7 +13270,6 @@ E499143F174E605900741B6D /* AliasShortcutUtils.cpp in Sources */, E4991440174E605900741B6D /* Archive.cpp in Sources */, E4991441174E605900741B6D /* AsyncFileCopy.cpp in Sources */, - E4991442174E605900741B6D /* AutoPtrHandle.cpp in Sources */, E4991443174E605900741B6D /* Base64.cpp in Sources */, E4991444174E605900741B6D /* BitstreamConverter.cpp in Sources */, E4991445174E605900741B6D /* BitstreamStats.cpp in Sources */, @@ -13627,6 +13599,7 @@ 7CCDA819192756250074CF51 /* NptSockets.cpp in Sources */, 7CCDA822192756250074CF51 /* NptStreams.cpp in Sources */, 7CCDA82B192756250074CF51 /* NptStrings.cpp in Sources */, + 7C226E3F1BA5F61D00185CE0 /* AddonCallbacksAudioEngine.cpp in Sources */, 7CCDA834192756250074CF51 /* NptSystem.cpp in Sources */, 7CCDA83D192756250074CF51 /* NptThreads.cpp in Sources */, 7CCDA846192756250074CF51 /* NptTime.cpp in Sources */, diff --git a/Makefile.in b/Makefile.in index 1ef3862419..e7276bfe1e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -194,6 +194,7 @@ LIB_DIRS=\ LIBADDON_DIRS=\ lib/addons/library.xbmc.addon \ lib/addons/library.kodi.adsp \ + lib/addons/library.kodi.audioengine \ lib/addons/library.xbmc.codec \ lib/addons/library.xbmc.pvr \ lib/addons/library.kodi.guilib \ @@ -331,6 +332,7 @@ dllloader: exports xbmc/cores/DllLoader/dllloader.a libaddon: exports $(MAKE) -C lib/addons/library.xbmc.addon $(MAKE) -C lib/addons/library.kodi.adsp + $(MAKE) -C lib/addons/library.kodi.audioengine $(MAKE) -C lib/addons/library.xbmc.codec $(MAKE) -C lib/addons/library.kodi.guilib $(MAKE) -C lib/addons/library.xbmc.pvr diff --git a/Makefile.include.in b/Makefile.include.in index e54672c695..471933991c 100644 --- a/Makefile.include.in +++ b/Makefile.include.in @@ -43,6 +43,7 @@ INCLUDES+=-I@abs_top_srcdir@/xbmc/addons/include INCLUDES+=-I@abs_top_srcdir@/addons/library.kodi.guilib INCLUDES+=-I@abs_top_srcdir@/addons/library.xbmc.addon INCLUDES+=-I@abs_top_srcdir@/addons/library.kodi.adsp +INCLUDES+=-I@abs_top_srcdir@/addons/library.kodi.audioengine INCLUDES+=-I@abs_top_srcdir@/addons/library.xbmc.pvr INCLUDES+=-I@abs_top_srcdir@/addons/library.xbmc.codec INCLUDES+=$(sort @INCLUDES@) diff --git a/addons/library.kodi.audioengine/libKODI_audioengine.h b/addons/library.kodi.audioengine/libKODI_audioengine.h new file mode 100644 index 0000000000..58e59cf9d0 --- /dev/null +++ b/addons/library.kodi.audioengine/libKODI_audioengine.h @@ -0,0 +1,332 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team KODI + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include <string.h> +#include <vector> + +#ifdef BUILD_KODI_ADDON + #include "kodi/AudioEngine/AEChannelData.h" + #include "kodi/AudioEngine/AEChannelInfo.h" + #include "kodi/AudioEngine/AEStreamData.h" + #include "kodi/AudioEngine/kodi_audioengine_types.h" +#else + #include "cores/AudioEngine/Utils/AEChannelData.h" + #include "cores/AudioEngine/Utils/AEChannelInfo.h" + #include "cores/AudioEngine/Utils/AEStreamData.h" + #include "addons/include/kodi_audioengine_types.h" +#endif + +#include "libXBMC_addon.h" + +#ifdef _WIN32 +#define AUDIOENGINE_HELPER_DLL "\\library.kodi.audioengine\\libKODI_audioengine" ADDON_HELPER_EXT +#else +#define AUDIOENGINE_HELPER_DLL_NAME "libKODI_audioengine-" ADDON_HELPER_ARCH ADDON_HELPER_EXT +#define AUDIOENGINE_HELPER_DLL "/library.kodi.audioengine/" AUDIOENGINE_HELPER_DLL_NAME +#endif + +class CAddonAEStream; + +class CHelper_libKODI_audioengine +{ +public: + CHelper_libKODI_audioengine(void) + { + m_libKODI_audioengine = NULL; + m_Handle = NULL; + } + + ~CHelper_libKODI_audioengine(void) + { + if (m_libKODI_audioengine) + { + AudioEngine_unregister_me(m_Handle, m_Callbacks); + dlclose(m_libKODI_audioengine); + } + } + + /*! + * @brief Resolve all callback methods + * @param handle Pointer to the add-on + * @return True when all methods were resolved, false otherwise. + */ + bool RegisterMe(void* handle) + { + m_Handle = handle; + + std::string libBasePath; + libBasePath = ((cb_array*)m_Handle)->libPath; + libBasePath += AUDIOENGINE_HELPER_DLL; + +#if defined(ANDROID) + struct stat st; + if(stat(libBasePath.c_str(),&st) != 0) + { + std::string tempbin = getenv("XBMC_ANDROID_LIBS"); + libBasePath = tempbin + "/" + AUDIOENGINE_HELPER_DLL; + } +#endif + + m_libKODI_audioengine = dlopen(libBasePath.c_str(), RTLD_LAZY); + if (m_libKODI_audioengine == NULL) + { + fprintf(stderr, "Unable to load %s\n", dlerror()); + return false; + } + + AudioEngine_register_me = (void* (*)(void *HANDLE)) + dlsym(m_libKODI_audioengine, "AudioEngine_register_me"); + if (AudioEngine_register_me == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + AudioEngine_unregister_me = (void(*)(void* HANDLE, void* CB)) + dlsym(m_libKODI_audioengine, "AudioEngine_unregister_me"); + if (AudioEngine_unregister_me == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + AudioEngine_MakeStream = (CAddonAEStream* (*)(void*, void*, AEDataFormat, unsigned int, unsigned int, enum AEChannel*, unsigned int)) + dlsym(m_libKODI_audioengine, "AudioEngine_make_stream"); + if (AudioEngine_MakeStream == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + AudioEngine_FreeStream = (void(*)(CAddonAEStream*)) + dlsym(m_libKODI_audioengine, "AudioEngine_free_stream"); + if (AudioEngine_FreeStream == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + AudioEngine_GetCurrentSinkFormat = (bool(*)(void*, void*, AudioEngineFormat*)) + dlsym(m_libKODI_audioengine, "AudioEngine_get_current_sink_Format"); + if (AudioEngine_GetCurrentSinkFormat == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + m_Callbacks = AudioEngine_register_me(m_Handle); + return m_Callbacks != NULL; + } + + /** + * Creates and returns a new handle to an IAEStream in the format specified, this function should never fail + * @param DataFormat The data format the incoming audio will be in (eg, AE_FMT_S16LE) + * @param SampleRate The sample rate of the audio data (eg, 48000) + * @prarm EncodedSampleRate The sample rate of the encoded audio data if AE_IS_RAW(dataFormat) + * @param ChannelLayout The order of the channels in the audio data + * @param Options A bit field of stream options (see: enum AEStreamOptions) + * @return a new Handle to an IAEStream that will accept data in the requested format + */ + CAddonAEStream* MakeStream(AEDataFormat DataFormat, unsigned int SampleRate, unsigned int EncodedSampleRate, CAEChannelInfo &ChannelLayout, unsigned int Options = 0) + { + return AudioEngine_MakeStream(m_Handle, m_Callbacks, DataFormat, SampleRate, EncodedSampleRate, ChannelLayout.m_channels, Options); + } + + /** + * This method will remove the specifyed stream from the engine. + * For OSX/IOS this is essential to reconfigure the audio output. + * @param stream The stream to be altered + * @return NULL + */ + void FreeStream(CAddonAEStream **Stream) + { + AudioEngine_FreeStream(*Stream); + *Stream = NULL; + } + + /** + * Get the current sink data format + * + * @param Current sink data format. For more details see AudioEngineFormat. + * @return Returns true on success, else false. + */ + bool GetCurrentSinkFormat(AudioEngineFormat &SinkFormat) + { + return AudioEngine_GetCurrentSinkFormat(m_Handle, m_Callbacks, &SinkFormat); + } + +protected: + void* (*AudioEngine_register_me)(void*); + void (*AudioEngine_unregister_me)(void*, void*); + CAddonAEStream* (*AudioEngine_MakeStream)(void*, void*, AEDataFormat, unsigned int, unsigned int, enum AEChannel*, unsigned int); + bool (*AudioEngine_GetCurrentSinkFormat)(void*, void*, AudioEngineFormat *SinkFormat); + void (*AudioEngine_FreeStream)(CAddonAEStream*); + +private: + void* m_libKODI_audioengine; + void* m_Handle; + void* m_Callbacks; + struct cb_array + { + const char* libPath; + }; +}; + +// Audio Engine Stream Class +class CAddonAEStream +{ +public: + CAddonAEStream(void *Addon, void *Callbacks, AEStreamHandle *StreamHandle); + virtual ~CAddonAEStream(); + + /** + * Returns the amount of space available in the stream + * @return The number of bytes AddData will consume + */ + virtual unsigned int GetSpace(); + + /** + * Add planar or interleaved PCM data to the stream + * @param Data array of pointers to the planes + * @param Offset to frame in frames + * @param Frames number of frames + * @return The number of frames consumed + */ + virtual unsigned int AddData(uint8_t* const *Data, unsigned int Offset, unsigned int Frames); + + /** + * Returns the time in seconds that it will take + * for the next added packet to be heard from the speakers. + * @return seconds + */ + virtual double GetDelay(); + + /** + * Returns if the stream is buffering + * @return True if the stream is buffering + */ + virtual bool IsBuffering(); + + /** + * Returns the time in seconds that it will take + * to underrun the cache if no sample is added. + * @return seconds + */ + virtual double GetCacheTime(); + + /** + * Returns the total time in seconds of the cache + * @return seconds + */ + virtual double GetCacheTotal(); + + /** + * Pauses the stream playback + */ + virtual void Pause(); + + /** + * Resumes the stream after pausing + */ + virtual void Resume(); + + /** + * Start draining the stream + * @note Once called AddData will not consume more data. + */ + virtual void Drain(bool Wait); + + /** + * Returns true if the is stream draining + */ + virtual bool IsDraining(); + + /** + * Returns true if the is stream has finished draining + */ + virtual bool IsDrained(); + + /** + * Flush all buffers dropping the audio data + */ + virtual void Flush(); + + /** + * Return the stream's current volume level + * @return The volume level between 0.0 and 1.0 + */ + virtual float GetVolume(); + + /** + * Set the stream's volume level + * @param volume The new volume level between 0.0 and 1.0 + */ + virtual void SetVolume(float Volume); + + /** + * Gets the stream's volume amplification in linear units. + * @return The volume amplification factor between 1.0 and 1000.0 + */ + virtual float GetAmplification(); + + /** + * Sets the stream's volume amplification in linear units. + * @param The volume amplification factor between 1.0 and 1000.0 + */ + virtual void SetAmplification(float Amplify); + + /** + * Returns the size of one audio frame in bytes (channelCount * resolution) + * @return The size in bytes of one frame + */ + virtual const unsigned int GetFrameSize() const; + + /** + * Returns the number of channels the stream is configured to accept + * @return The channel count + */ + virtual const unsigned int GetChannelCount() const; + + /** + * Returns the stream's sample rate, if the stream is using a dynamic sample rate, this value will NOT reflect any changes made by calls to SetResampleRatio() + * @return The stream's sample rate (eg, 48000) + */ + virtual const unsigned int GetSampleRate() const; + + /** + * Returns the stream's encoded sample rate if the stream is RAW + * @return The stream's encoded sample rate + */ + virtual const unsigned int GetEncodedSampleRate() const; + + /** + * Return the data format the stream has been configured with + * @return The stream's data format (eg, AE_FMT_S16LE) + */ + virtual const AEDataFormat GetDataFormat() const; + + /** + * Return the resample ratio + * @note This will return an undefined value if the stream is not resampling + * @return the current resample ratio or undefined if the stream is not resampling + */ + virtual double GetResampleRatio(); + + /** + * Sets the resample ratio + * @note This function may return false if the stream is not resampling, if you wish to use this be sure to set the AESTREAM_FORCE_RESAMPLE option + * @param ratio the new sample rate ratio, calculated by ((double)desiredRate / (double)GetSampleRate()) + */ + virtual bool SetResampleRatio(double Ratio); + + /** + * Sginal a clock change + */ + virtual void Discontinuity(); + + private: + AEStreamHandle *m_StreamHandle; + void *m_Callbacks; + void *m_AddonHandle; +}; diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index e3135577ce..07bdb00bc3 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -5798,6 +5798,7 @@ msgctxt "#13204" msgid "Last loaded profile:" msgstr "" +#: xbmc/addons/GUIDialogAddonInfo.cpp #: xbmc/music/karaoke/GUIDialogKaraokeSongSelector.cpp #: xbmc/peripherals/devices/Peripheral.cpp #: xbmc/peripherals/bus/PeripheralBus.cpp @@ -11930,7 +11931,12 @@ msgctxt "#20469" msgid "Keep current set (%s)" msgstr "" -#empty strings from id 20470 to 21329 +#: system/settings/settings.xml +msgctxt "#20470" +msgid "Group single movies into sets" +msgstr "" + +#empty strings from id 20471 to 21329 #up to 21329 is reserved for the video db !! ! #: system/settings/settings.xml @@ -11974,7 +11980,17 @@ msgctxt "#21337" msgid "Never" msgstr "" -#empty strings from id 21338 to 21358 +#: xbmc/addons/GUIDialogAddonInfo.cpp +msgctxt "#21338" +msgid "Select version" +msgstr "" + +#: xbmc/addons/GUIDialogAddonInfo.cpp +msgctxt "#21339" +msgid "Version %s" +msgstr "" + +#empty strings from id 21340 to 21358 #: xbmc/dialogs/GUIDialogFileBrowser.cpp msgctxt "#21359" @@ -12529,7 +12545,22 @@ msgctxt "#21477" msgid "Just \"Specials\"" msgstr "" -#empty strings from id 21478 to 21601 +#: xbmc/addons/GUIDialogAddonInfo.cpp +msgctxt "#21478" +msgid "Open" +msgstr "" + +#: xbmc/addons/GUIDialogAddonInfo.cpp +msgctxt "#21479" +msgid "Run" +msgstr "" + +#: xbmc/addons/GUIDialogAddonInfo.cpp +msgctxt "#21480" +msgid "Use" +msgstr "" + +#empty strings from id 21481 to 21601 #: xbmc/Util.cpp msgctxt "#21602" @@ -15795,7 +15826,11 @@ msgctxt "#36156" msgid "Enable VAAPI hardware decoding of video files, mainly used for Intel graphics and in some circumstances AMD graphics." msgstr "" -#empty string with id 36157 +#. Description of setting "Videos -> Library -> Group single movies into sets" with label #20470 +#: system/settings/settings.xml +msgctxt "#36157" +msgid "When scanned into the library a movie may be identified as forming part of a \"Movie set\". With this setting enabled you may get movie sets displayed that contain only a single movie. If it is disabled only movie sets with multiple movies will be displayed." +msgstr "" #. Description of setting "Videos -> Playback -> Allow hardware acceleration (DXVA2)" with label #13427 #: system/settings/settings.xml diff --git a/addons/skin.confluence/720p/AddonBrowser.xml b/addons/skin.confluence/720p/AddonBrowser.xml index 47578eaaed..d7b681f401 100644 --- a/addons/skin.confluence/720p/AddonBrowser.xml +++ b/addons/skin.confluence/720p/AddonBrowser.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <views>50,51,550,551</views> <controls> diff --git a/addons/skin.confluence/720p/DialogAlbumInfo.xml b/addons/skin.confluence/720p/DialogAlbumInfo.xml index c8a3bef813..56f82a8eba 100644 --- a/addons/skin.confluence/720p/DialogAlbumInfo.xml +++ b/addons/skin.confluence/720p/DialogAlbumInfo.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">5</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <control type="group"> <visible>!Window.IsVisible(FileBrowser)</visible> diff --git a/addons/skin.confluence/720p/DialogAudioDSPManager.xml b/addons/skin.confluence/720p/DialogAudioDSPManager.xml index 965ff7e7d9..62cedc76bf 100644 --- a/addons/skin.confluence/720p/DialogAudioDSPManager.xml +++ b/addons/skin.confluence/720p/DialogAudioDSPManager.xml @@ -3,7 +3,6 @@ <zorder>1</zorder> <defaultcontrol>9000</defaultcontrol> <include>dialogeffect</include> - <allowoverlay>no</allowoverlay> <coordinates> <left>40</left> <top>40</top> diff --git a/addons/skin.confluence/720p/DialogNumeric.xml b/addons/skin.confluence/720p/DialogNumeric.xml index 446d70418c..a94f7436d8 100644 --- a/addons/skin.confluence/720p/DialogNumeric.xml +++ b/addons/skin.confluence/720p/DialogNumeric.xml @@ -3,30 +3,43 @@ <defaultcontrol always="true">21</defaultcontrol> <include>dialogeffect</include> <coordinates> - <left>510</left> - <top>115</top> + <left>420</left> + <top>175</top> </coordinates> <controls> <control type="image"> <left>0</left> <top>0</top> - <width>260</width> - <height>490</height> + <width>380</width> + <height>430</height> <texture border="40">DialogBack.png</texture> </control> <control type="image"> <description>Dialog Header image</description> <left>40</left> - <top>16</top> - <width>180</width> - <height>40</height> + <top>18</top> + <width>300</width> + <height>50</height> <texture>dialogheader.png</texture> </control> + <control type="button"> + <description>Close Window button</description> + <left>290</left> + <top>15</top> + <width>64</width> + <height>32</height> + <label>-</label> + <font>-</font> + <onclick>PreviousMenu</onclick> + <texturefocus>DialogCloseButton-focus.png</texturefocus> + <texturenofocus>DialogCloseButton.png</texturenofocus> + <visible>system.getbool(input.enablemouse)</visible> + </control> <control type="label" id="1"> <description>dialog Heading</description> <left>20</left> - <top>20</top> - <width>220</width> + <top>28</top> + <width>340</width> <height>35</height> <font>font12_title</font> <textcolor>selected</textcolor> @@ -38,7 +51,7 @@ <control type="image"> <left>30</left> <top>70</top> - <width>200</width> + <width>320</width> <height>50</height> <aspectratio>stretch</aspectratio> <texture border="20">KeyboardEditArea.png</texture> @@ -47,7 +60,7 @@ <description>Edit Text</description> <left>35</left> <top>70</top> - <width>190</width> + <width>310</width> <height>50</height> <font>font13</font> <textcolor>selected</textcolor> @@ -58,13 +71,13 @@ <control type="image"> <left>40</left> <top>120</top> - <width>180</width> + <width>300</width> <height>30</height> <aspectratio>stretch</aspectratio> <texture>dialogheader.png</texture> </control> <control type="group"> - <left>40</left> + <left>55</left> <top>155</top> <control type="button" id="11"> <description>1 button</description> @@ -79,9 +92,9 @@ <texturefocus border="25,25,5,5">KeyboardCornerTop.png</texturefocus> <label>12311</label> <focusedcolor>black</focusedcolor> - <onleft>13</onleft> + <onleft>23</onleft> <onright>12</onright> - <onup>21</onup> + <onup>20</onup> <ondown>14</ondown> </control> <control type="button" id="12"> @@ -99,7 +112,7 @@ <focusedcolor>black</focusedcolor> <onleft>11</onleft> <onright>13</onright> - <onup>21</onup> + <onup>10</onup> <ondown>15</ondown> </control> <control type="button" id="13"> @@ -111,15 +124,42 @@ <font>font13</font> <align>center</align> <aligny>center</aligny> - <texturenofocus flipx="true" border="5,25,25,5">KeyboardCornerTopNF.png</texturenofocus> - <texturefocus flipx="true" border="5,25,25,5">KeyboardCornerTop.png</texturefocus> + <texturenofocus border="3">KeyboardKeyNF.png</texturenofocus> + <texturefocus border="5">KeyboardKey.png</texturefocus> <label>12313</label> <focusedcolor>black</focusedcolor> <onleft>12</onleft> - <onright>11</onright> - <onup>23</onup> + <onright>23</onright> + <onup>22</onup> <ondown>16</ondown> </control> + <control type="button" id="23"> + <description>Backspace button</description> + <left>180</left> + <top>0</top> + <width>90</width> + <height>120</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <texturenofocus flipx="true" border="5,25,25,5">KeyboardCornerTopNF.png</texturenofocus> + <texturefocus flipx="true" border="5,25,25,5">KeyboardCornerTop.png</texturefocus> + <textwidth>120</textwidth> + <label>-</label> + <focusedcolor>black</focusedcolor> + <onleft>13</onleft> + <onright>11</onright> + <onup>21</onup> + <ondown>21</ondown> + </control> + <control type="image"> + <description>Backspace icon</description> + <left>210</left> + <top>45</top> + <width>30</width> + <height>30</height> + <texture>KeyboardBackKey.png</texture> + </control> <control type="button" id="14"> <description>4 button</description> <left>0</left> @@ -133,7 +173,7 @@ <texturefocus border="5">KeyboardKey.png</texturefocus> <label>12314</label> <focusedcolor>black</focusedcolor> - <onleft>16</onleft> + <onleft>23</onleft> <onright>15</onright> <onup>11</onup> <ondown>17</ondown> @@ -170,7 +210,7 @@ <label>12316</label> <focusedcolor>black</focusedcolor> <onleft>15</onleft> - <onright>14</onright> + <onright>23</onright> <onup>13</onup> <ondown>19</ondown> </control> @@ -187,7 +227,7 @@ <texturefocus border="5">KeyboardKey.png</texturefocus> <label>12317</label> <focusedcolor>black</focusedcolor> - <onleft>19</onleft> + <onleft>21</onleft> <onright>18</onright> <onup>14</onup> <ondown>20</ondown> @@ -224,10 +264,37 @@ <label>12319</label> <focusedcolor>black</focusedcolor> <onleft>18</onleft> - <onright>17</onright> + <onright>21</onright> <onup>16</onup> <ondown>22</ondown> </control> + <control type="button" id="21"> + <description>Done button</description> + <left>180</left> + <top>120</top> + <width>90</width> + <height>120</height> + <font>font12</font> + <align>center</align> + <aligny>center</aligny> + <texturenofocus flipx="true" border="25,5,5,25">KeyboardCornerBottomNF.png</texturenofocus> + <texturefocus flipx="true" border="5,5,25,25">KeyboardCornerBottom.png</texturefocus> + <textwidth>120</textwidth> + <label>-</label> + <focusedcolor>black</focusedcolor> + <onleft>19</onleft> + <onright>17</onright> + <onup>23</onup> + <ondown>23</ondown> + </control> + <control type="image"> + <description>Done icon</description> + <left>210</left> + <top>165</top> + <width>30</width> + <height>30</height> + <texture>KeyboardDoneKey.png</texture> + </control> <control type="button" id="20"> <description>prev button</description> <left>0</left> @@ -239,12 +306,12 @@ <focusedcolor>black</focusedcolor> <align>center</align> <aligny>center</aligny> - <texturenofocus border="3">KeyboardKeyNF.png</texturenofocus> - <texturefocus border="5">KeyboardKey.png</texturefocus> - <onleft>22</onleft> + <texturenofocus border="5,25,25,5">KeyboardCornerBottomNF.png</texturenofocus> + <texturefocus border="5,25,25,5">KeyboardCornerBottom.png</texturefocus> + <onleft>21</onleft> <onright>10</onright> <onup>17</onup> - <ondown>21</ondown> + <ondown>11</ondown> </control> <control type="button" id="10"> <description>0 button</description> @@ -262,7 +329,7 @@ <onleft>20</onleft> <onright>22</onright> <onup>18</onup> - <ondown>21</ondown> + <ondown>12</ondown> </control> <control type="button" id="22"> <description>next button</description> @@ -278,56 +345,10 @@ <texturenofocus border="3">KeyboardKeyNF.png</texturenofocus> <texturefocus border="5">KeyboardKey.png</texturefocus> <onleft>10</onleft> - <onright>20</onright> - <onup>19</onup> - <ondown>23</ondown> - </control> - <control type="button" id="21"> - <description>Done button</description> - <left>0</left> - <top>240</top> - <width>90</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <texturenofocus border="5,25,25,5">KeyboardCornerBottomNF.png</texturenofocus> - <texturefocus border="5,25,25,5">KeyboardCornerBottom.png</texturefocus> - <textwidth>120</textwidth> - <label>186</label> - <focusedcolor>black</focusedcolor> - <onleft>23</onleft> - <onright>23</onright> - <onup>20</onup> - <ondown>11</ondown> - </control> - <control type="button" id="23"> - <description>Backspace button</description> - <left>90</left> - <top>240</top> - <width>90</width> - <height>60</height> - <font>font12</font> - <align>center</align> - <aligny>center</aligny> - <texturenofocus flipx="true" border="25,5,5,25">KeyboardCornerBottomNF.png</texturenofocus> - <texturefocus flipx="true" border="5,5,25,25">KeyboardCornerBottom.png</texturefocus> - <textwidth>120</textwidth> - <label>-</label> - <focusedcolor>black</focusedcolor> - <onleft>21</onleft> <onright>21</onright> - <onup>22</onup> + <onup>19</onup> <ondown>13</ondown> </control> - <control type="image"> - <description>Backspace button</description> - <left>123</left> - <top>258</top> - <width>24</width> - <height>24</height> - <texture>KeyboardBackKey.png</texture> - </control> </control> </controls> </window> diff --git a/addons/skin.confluence/720p/DialogPVRChannelManager.xml b/addons/skin.confluence/720p/DialogPVRChannelManager.xml index b122979407..d81bf97aaa 100644 --- a/addons/skin.confluence/720p/DialogPVRChannelManager.xml +++ b/addons/skin.confluence/720p/DialogPVRChannelManager.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">20</defaultcontrol> - <allowoverlay>no</allowoverlay> <coordinates> <left>80</left> <top>65</top> diff --git a/addons/skin.confluence/720p/DialogVideoInfo.xml b/addons/skin.confluence/720p/DialogVideoInfo.xml index 9479c0dc3c..c60ff901a2 100644 --- a/addons/skin.confluence/720p/DialogVideoInfo.xml +++ b/addons/skin.confluence/720p/DialogVideoInfo.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">8</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <control type="group"> <visible>!Window.IsVisible(FileBrowser)</visible> diff --git a/addons/skin.confluence/720p/EventLog.xml b/addons/skin.confluence/720p/EventLog.xml index 58821cefc7..5e6c074a6a 100644 --- a/addons/skin.confluence/720p/EventLog.xml +++ b/addons/skin.confluence/720p/EventLog.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">570</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <views>570</views> <controls> diff --git a/addons/skin.confluence/720p/FileBrowser.xml b/addons/skin.confluence/720p/FileBrowser.xml index 83995fd008..be0bdb0b6c 100644 --- a/addons/skin.confluence/720p/FileBrowser.xml +++ b/addons/skin.confluence/720p/FileBrowser.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">450</defaultcontrol> - <allowoverlay>no</allowoverlay> <coordinates> <left>0</left> <top>0</top> diff --git a/addons/skin.confluence/720p/FileManager.xml b/addons/skin.confluence/720p/FileManager.xml index 2bf396ec98..8c1c157ade 100644 --- a/addons/skin.confluence/720p/FileManager.xml +++ b/addons/skin.confluence/720p/FileManager.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol>20</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <include>CommonBackground</include> <control type="image"> diff --git a/addons/skin.confluence/720p/Home.xml b/addons/skin.confluence/720p/Home.xml index e08cb1c9c0..63394e6fad 100644 --- a/addons/skin.confluence/720p/Home.xml +++ b/addons/skin.confluence/720p/Home.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">9000</defaultcontrol> - <allowoverlay>no</allowoverlay> <onunload condition="Container(9000).Hasfocus(10) | Container(9000).Hasfocus(11) | ControlGroup(9010).HasFocus | ControlGroup(9016).HasFocus | ControlGroup(9017).HasFocus">SetProperty(VideosDirectLink,True)</onunload> <onunload condition="ControlGroup(9011).HasFocus">SetProperty(MusicDirectLink,True)</onunload> <onunload condition="Control.HasFocus(9000) + Container(9000).Hasfocus(2)">ClearProperty(VideosDirectLink)</onunload> diff --git a/addons/skin.confluence/720p/LoginScreen.xml b/addons/skin.confluence/720p/LoginScreen.xml index 869da79b0a..636df255ba 100644 --- a/addons/skin.confluence/720p/LoginScreen.xml +++ b/addons/skin.confluence/720p/LoginScreen.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">52</defaultcontrol> - <allowoverlay>no</allowoverlay> <coordinates> <left>0</left> <top>0</top> diff --git a/addons/skin.confluence/720p/MusicVisualisation.xml b/addons/skin.confluence/720p/MusicVisualisation.xml index 00c183fee3..3b97ac73b5 100644 --- a/addons/skin.confluence/720p/MusicVisualisation.xml +++ b/addons/skin.confluence/720p/MusicVisualisation.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol>-</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <control type="visualisation" id="2"> <!-- FIX ME Music Visualization needs to have an id of 2 in this window to be able to lock or change preset --> diff --git a/addons/skin.confluence/720p/MyMusicNav.xml b/addons/skin.confluence/720p/MyMusicNav.xml index 1c77ae3edc..e5ce705d05 100644 --- a/addons/skin.confluence/720p/MyMusicNav.xml +++ b/addons/skin.confluence/720p/MyMusicNav.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <views>50,51,500,550,551,509,506,511,512,513</views> <controls> diff --git a/addons/skin.confluence/720p/MyMusicPlaylist.xml b/addons/skin.confluence/720p/MyMusicPlaylist.xml index 70daf9b601..cdf36e6bc8 100644 --- a/addons/skin.confluence/720p/MyMusicPlaylist.xml +++ b/addons/skin.confluence/720p/MyMusicPlaylist.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <views>50,51,506</views> <controls> diff --git a/addons/skin.confluence/720p/MyMusicPlaylistEditor.xml b/addons/skin.confluence/720p/MyMusicPlaylistEditor.xml index 110d1f27a1..4a84581d8a 100644 --- a/addons/skin.confluence/720p/MyMusicPlaylistEditor.xml +++ b/addons/skin.confluence/720p/MyMusicPlaylistEditor.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">6</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <controls> <include>CommonBackground</include> <control type="group"> diff --git a/addons/skin.confluence/720p/MyPVRChannels.xml b/addons/skin.confluence/720p/MyPVRChannels.xml index fcc5e0c83b..64791e4cfc 100644 --- a/addons/skin.confluence/720p/MyPVRChannels.xml +++ b/addons/skin.confluence/720p/MyPVRChannels.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <views>50,51</views> <controls> <include>CommonBackground</include> diff --git a/addons/skin.confluence/720p/MyPVRGuide.xml b/addons/skin.confluence/720p/MyPVRGuide.xml index a1dd2a7225..51858c066f 100644 --- a/addons/skin.confluence/720p/MyPVRGuide.xml +++ b/addons/skin.confluence/720p/MyPVRGuide.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">10</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <views>10,11,12,13</views> <controls> <include>CommonBackground</include> diff --git a/addons/skin.confluence/720p/MyPVRRecordings.xml b/addons/skin.confluence/720p/MyPVRRecordings.xml index b517e6864e..f5a102746e 100644 --- a/addons/skin.confluence/720p/MyPVRRecordings.xml +++ b/addons/skin.confluence/720p/MyPVRRecordings.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <views>50</views> <controls> <include>CommonBackground</include> diff --git a/addons/skin.confluence/720p/MyPVRSearch.xml b/addons/skin.confluence/720p/MyPVRSearch.xml index 417a684c31..7fe84d4d92 100644 --- a/addons/skin.confluence/720p/MyPVRSearch.xml +++ b/addons/skin.confluence/720p/MyPVRSearch.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <views>50</views> <controls> <include>CommonBackground</include> diff --git a/addons/skin.confluence/720p/MyPVRTimers.xml b/addons/skin.confluence/720p/MyPVRTimers.xml index a20d2352e9..1b477ad887 100644 --- a/addons/skin.confluence/720p/MyPVRTimers.xml +++ b/addons/skin.confluence/720p/MyPVRTimers.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <views>50</views> <controls> <include>CommonBackground</include> diff --git a/addons/skin.confluence/720p/MyPics.xml b/addons/skin.confluence/720p/MyPics.xml index b84fc2f9b4..4d97566c41 100644 --- a/addons/skin.confluence/720p/MyPics.xml +++ b/addons/skin.confluence/720p/MyPics.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <views>50,51,550,551,500,514,510</views> <controls> diff --git a/addons/skin.confluence/720p/MyPrograms.xml b/addons/skin.confluence/720p/MyPrograms.xml index cc5bd98f65..607a05719f 100644 --- a/addons/skin.confluence/720p/MyPrograms.xml +++ b/addons/skin.confluence/720p/MyPrograms.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <views>50,51,500,550,551</views> <controls> diff --git a/addons/skin.confluence/720p/MyVideoNav.xml b/addons/skin.confluence/720p/MyVideoNav.xml index cd5ff0e231..e41d6b7e43 100644 --- a/addons/skin.confluence/720p/MyVideoNav.xml +++ b/addons/skin.confluence/720p/MyVideoNav.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <views>50,51,500,550,551,560,501,508,504,503,515,505,511</views> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <controls> diff --git a/addons/skin.confluence/720p/MyVideoPlaylist.xml b/addons/skin.confluence/720p/MyVideoPlaylist.xml index b70ac5b022..e9cf5b9cf9 100644 --- a/addons/skin.confluence/720p/MyVideoPlaylist.xml +++ b/addons/skin.confluence/720p/MyVideoPlaylist.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <views>50,51</views> <controls> diff --git a/addons/skin.confluence/720p/MyWeather.xml b/addons/skin.confluence/720p/MyWeather.xml index ce2531a316..425b0f66f6 100644 --- a/addons/skin.confluence/720p/MyWeather.xml +++ b/addons/skin.confluence/720p/MyWeather.xml @@ -2,7 +2,6 @@ <window> <defaultcontrol always="true">50</defaultcontrol> <menucontrol>9000</menucontrol> - <allowoverlay>no</allowoverlay> <onload condition="!Skin.HasSetting(FirstTimeRun)">ActivateWindow(1112)</onload> <controls> <include>CommonBackground</include> diff --git a/addons/skin.confluence/720p/Settings.xml b/addons/skin.confluence/720p/Settings.xml index e2332758f5..295ebfe52b 100644 --- a/addons/skin.confluence/720p/Settings.xml +++ b/addons/skin.confluence/720p/Settings.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">9000</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <include>CommonBackground</include> <control type="image"> diff --git a/addons/skin.confluence/720p/SettingsCategory.xml b/addons/skin.confluence/720p/SettingsCategory.xml index 857f7b6a8f..cd8a9050f3 100644 --- a/addons/skin.confluence/720p/SettingsCategory.xml +++ b/addons/skin.confluence/720p/SettingsCategory.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol>3</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <include>CommonBackground</include> <control type="image"> diff --git a/addons/skin.confluence/720p/SettingsProfile.xml b/addons/skin.confluence/720p/SettingsProfile.xml index 2cda4cd555..536730d57f 100644 --- a/addons/skin.confluence/720p/SettingsProfile.xml +++ b/addons/skin.confluence/720p/SettingsProfile.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">9000</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <include>CommonBackground</include> <control type="image"> diff --git a/addons/skin.confluence/720p/SettingsSystemInfo.xml b/addons/skin.confluence/720p/SettingsSystemInfo.xml index 0c9284d6bc..fd9fa1cc5e 100644 --- a/addons/skin.confluence/720p/SettingsSystemInfo.xml +++ b/addons/skin.confluence/720p/SettingsSystemInfo.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">95</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <include>CommonBackground</include> <control type="image"> diff --git a/addons/skin.confluence/720p/SmartPlaylistEditor.xml b/addons/skin.confluence/720p/SmartPlaylistEditor.xml index 4a924a7702..a35252433b 100644 --- a/addons/skin.confluence/720p/SmartPlaylistEditor.xml +++ b/addons/skin.confluence/720p/SmartPlaylistEditor.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">22</defaultcontrol> - <allowoverlay>no</allowoverlay> <coordinates> <left>240</left> <top>22</top> diff --git a/addons/skin.confluence/720p/SmartPlaylistRule.xml b/addons/skin.confluence/720p/SmartPlaylistRule.xml index ecaca05a8c..fdc89f4f62 100644 --- a/addons/skin.confluence/720p/SmartPlaylistRule.xml +++ b/addons/skin.confluence/720p/SmartPlaylistRule.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">9001</defaultcontrol> - <allowoverlay>no</allowoverlay> <coordinates> <left>240</left> <top>220</top> diff --git a/addons/skin.confluence/720p/Startup.xml b/addons/skin.confluence/720p/Startup.xml index 455f71fe19..c8b81856ad 100644 --- a/addons/skin.confluence/720p/Startup.xml +++ b/addons/skin.confluence/720p/Startup.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <window> <defaultcontrol always="true">10</defaultcontrol> - <allowoverlay>no</allowoverlay> <controls> <control type="button" id="10"> <description>trigger</description> diff --git a/addons/skin.confluence/720p/script-NextAired-TVGuide.xml b/addons/skin.confluence/720p/script-NextAired-TVGuide.xml index 9b96d728ca..27e1093408 100644 --- a/addons/skin.confluence/720p/script-NextAired-TVGuide.xml +++ b/addons/skin.confluence/720p/script-NextAired-TVGuide.xml @@ -7,7 +7,6 @@ <onload>ClearProperty(TVGuide.FridayList,Home)</onload> <onload>ClearProperty(TVGuide.SaturdayList,Home)</onload> <onload>ClearProperty(TVGuide.SundayList,Home)</onload> - <allowoverlay>no</allowoverlay> <controls> <include>CommonBackground</include> <control type="group"> diff --git a/addons/skin.confluence/720p/script-cu-lrclyrics-main.xml b/addons/skin.confluence/720p/script-cu-lrclyrics-main.xml index 3b9c6fce47..f7ba7b5431 100644 --- a/addons/skin.confluence/720p/script-cu-lrclyrics-main.xml +++ b/addons/skin.confluence/720p/script-cu-lrclyrics-main.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <window> - <allowoverlay>no</allowoverlay> <coordinates> <left>680</left> <top>0</top> diff --git a/addons/skin.confluence/720p/script-globalsearch-main.xml b/addons/skin.confluence/720p/script-globalsearch-main.xml index 75fad30293..9809708348 100644 --- a/addons/skin.confluence/720p/script-globalsearch-main.xml +++ b/addons/skin.confluence/720p/script-globalsearch-main.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <window> - <allowoverlay>no</allowoverlay> <coordinates> <left>0</left> <top>0</top> diff --git a/addons/skin.confluence/media/KeyboardDoneKey.png b/addons/skin.confluence/media/KeyboardDoneKey.png Binary files differnew file mode 100644 index 0000000000..d76cb59369 --- /dev/null +++ b/addons/skin.confluence/media/KeyboardDoneKey.png diff --git a/addons/skin.re-touched b/addons/skin.re-touched -Subproject 8d6616fffba8b15533195bd7e65d3f35c6dc51e +Subproject db5f915d02c315d5d23f7de8173f9ec0646cf15 diff --git a/addons/xbmc.pvr/addon.xml b/addons/xbmc.pvr/addon.xml index 1e065230a1..fc35d641c7 100644 --- a/addons/xbmc.pvr/addon.xml +++ b/addons/xbmc.pvr/addon.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="xbmc.pvr" version="4.0.0" provider-name="Team-Kodi"> - <backwards-compatibility abi="4.0.0"/> +<addon id="xbmc.pvr" version="4.1.0" provider-name="Team-Kodi"> + <backwards-compatibility abi="4.1.0"/> <requires> <import addon="xbmc.core" version="0.1.0"/> </requires> diff --git a/configure.ac b/configure.ac index a861ce9378..eb558a82c6 100644 --- a/configure.ac +++ b/configure.ac @@ -2395,6 +2395,7 @@ OUTPUT_FILES="Makefile \ xbmc/windowing/egl/Makefile \ lib/addons/library.xbmc.addon/Makefile \ lib/addons/library.kodi.adsp/Makefile \ + lib/addons/library.kodi.audioengine/Makefile \ lib/addons/library.xbmc.codec/Makefile \ lib/addons/library.kodi.guilib/Makefile \ lib/addons/library.xbmc.pvr/Makefile \ diff --git a/docs/README.ios b/docs/README.ios index 2651aeb72c..c6da9028e7 100644 --- a/docs/README.ios +++ b/docs/README.ios @@ -18,7 +18,7 @@ TOC ----------------------------------------------------------------------------- This is a platform port of Kodi for the Apple iOS operating system. -The current build system supports Xcode 6.0.1 and 6.1.0 with iOS SDK 8.1 +The current build system supports Xcode 6.x and 7.x with iOS SDK 8.x and 9.x There are two ways to build Kodi for Mac. 1) command-line or @@ -57,6 +57,8 @@ Install latest Xcode (6.1.0 as of the writing). You can download it from Xcode 6.1.0 only runs on 10.9.5 and later (at least Mavericks). +Xcode 6.4.0 only runs on 10.10 and later (at least Yosemite). +Xcode 7.x only runs on 10.10 and later (at least Yosemite). The preferred iOS SDK Version is 8.1. @@ -70,6 +72,7 @@ constellations of Xcode and OSX versions (to be updated once we know more): 2. Xcode 6.1.0 against iOS SDK 8.1 on 10.10.x (Yosemite) 3. Xcode 6.3.0 against iOS SDK 8.3 on 10.10.x (Yosemite) 4. Xcode 6.4.0 against iOS SDK 8.4 on 10.10.x (Yosemite) +5. Xcode 7.x against iOS SDK 9.x on 10.10.x (Yosemite) ----------------------------------------------------------------------------- 3.2 Install Cross libs and runtime environment @@ -177,9 +180,8 @@ Gestures can be adapted in system/keymaps/touchscreen.xml If you are a developer with an official apple code signing identity you can deploy Kodi via xcode to work on it on non-jailbroken devices. For this to happen you just need to alter the -Xcode project by setting your codesign identity. Be sure to not just select the "iPhone Developer" shortcut -but instead select your full identity "iPhone Developer: your name (your id)" (this is important else our sign -script won't detect a real sign identity). Its also important that you select the signing on all 4 spots +Xcode project by setting your codesign identity. Just select the "iPhone Developer" shortcut. +Its also important that you select the signing on all 4 spots in the project settings. After that the last buildstep in our support script will do a full sign of all binaries and the bundle with the given identity (all *.viz, *.pvr, *.so files Xcode doesn't know anything about). This should allow you to deploy Kodi to all non-jailbroken devices @@ -187,3 +189,5 @@ which you can deploy normal apps to. In that case (Kodi will be sandboxed like a files are then located in the sandboxed "Documents" folder and can be easily accessed via iTunes file sharing. Keep in mind that no hardware acceleration will be possible without jailbreaking when using iOS < Version 8. + +From Xcode7 on - this approach is also available for non paying app developers (apple allows self signing from now on) diff --git a/docs/README.osx b/docs/README.osx index 1313829dc0..c42d411f7e 100644 --- a/docs/README.osx +++ b/docs/README.osx @@ -18,7 +18,7 @@ TOC ----------------------------------------------------------------------------- This is a platform port of Kodi for the Apple OSX operating system. 10.9 and 10.10 Intel development -platforms are supported. Xcode 6 newer are the recommended versions. +platforms are supported. Xcode 6 or newer are the recommended versions. There are 3 ways to build Kodi for Mac, from command-line with make, from command-line using xcodebuild or from Xcode. @@ -31,7 +31,7 @@ Kodi for Mac is composed of a main binary with numerous dynamic libraries and codecs that support a multitude of music and video formats. On Mavericks (OSX 10.9.x) we recommend using Xcode 6.1. -On Yosemite (OSX 10.10.x) we recommend using Xcode 6.1. +On Yosemite (OSX 10.10.x) we recommend using Xcode 6.4. NOTE TO NEW OS X USERS: All lines that are prefixed with the '$' character are commands that need to be typed into a Terminal window. Note that the '$' @@ -52,9 +52,9 @@ its not part of OSX anymore since 10.8. ----------------------------------------------------------------------------- See point 3.1.1 below for an updated list of supported/tested Xcode/osx constellations!!! -Install latest Xcode (6.1.0 ). You can download it from the MacOSX AppStore (Xcode). +Install latest Xcode (6.4.0 ). You can download it from the MacOSX AppStore (Xcode). -Xcode 6.1 runs on 10.9.5 and later (at least Mavericks). +Xcode 6.4 runs on 10.10 and later (at least Yosemite). ----------------------------------------------------------------------------- 3.1.1 Supported Xcode and OSX constellations @@ -66,6 +66,8 @@ constellations of Xcode and osx versions (to be updated once we know more): 2. XCode 6.1.0 against OSX SDK 10.10 (Y) 3. XCode 6.2.0 against OSX SDK 10.10 (Y) 4. XCode 6.3.0 against OSX SDK 10.10 (Y) +5. Xcode 6.4.0 against OSX SDK 10.10 (Y) +6. Xcode 7.x against OSX SDK 10.11 (Y) ----------------------------------------------------------------------------- 3.2 Install Kodi build depends diff --git a/lib/addons/library.kodi.audioengine/Makefile.in b/lib/addons/library.kodi.audioengine/Makefile.in new file mode 100644 index 0000000000..0acd0eec77 --- /dev/null +++ b/lib/addons/library.kodi.audioengine/Makefile.in @@ -0,0 +1,27 @@ +ARCH=@ARCH@ +INCLUDES=-I. -I../../../xbmc/addons/include -I../../../xbmc +DEFINES+= +CXXFLAGS=-fPIC +LIBNAME=libKODI_audioengine +OBJS=$(LIBNAME).o + +LIB_SHARED=../../../addons/library.kodi.audioengine/$(LIBNAME)-$(ARCH).so + +all: $(LIB_SHARED) + +$(LIB_SHARED): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(LDFLAGS) -Wl,-alias_list,@abs_top_srcdir@/xbmc/cores/DllLoader/exports/wrapper_mach_alias \ + -bundle -undefined dynamic_lookup -o $@ \ + @abs_top_srcdir@/xbmc/cores/DllLoader/exports/wrapper.o $(OBJS) +else + $(CXX) $(CFLAGS) $(LDFLAGS) -shared -g -o $(LIB_SHARED) $(OBJS) +endif + +CLEAN_FILES = \ + $(LIB_SHARED) \ + +DISTCLEAN_FILES= \ + Makefile \ + +include ../../../Makefile.include diff --git a/lib/addons/library.kodi.audioengine/libKODI_audioengine.cpp b/lib/addons/library.kodi.audioengine/libKODI_audioengine.cpp new file mode 100644 index 0000000000..e688d70e85 --- /dev/null +++ b/lib/addons/library.kodi.audioengine/libKODI_audioengine.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2013-2014 Team KODI + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include "../../../addons/library.kodi.audioengine/libKODI_audioengine.h" +#include "addons/AddonCallbacks.h" + +#ifdef _WIN32 +#include <windows.h> +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT +#endif + +using namespace std; + +#define LIBRARY_NAME "libKODI_audioengine" + +extern "C" +{ + +DLLEXPORT void* AudioEngine_register_me(void *hdl) +{ + CB_AudioEngineLib *cb = NULL; + if (!hdl) + fprintf(stderr, "%s-ERROR: AudioEngine_register_me is called with NULL handle !!!\n", LIBRARY_NAME); + else + { + cb = ((AddonCB*)hdl)->AudioEngineLib_RegisterMe(((AddonCB*)hdl)->addonData); + if (!cb) + fprintf(stderr, "%s-ERROR: AudioEngine_register_me can't get callback table from KODI !!!\n", LIBRARY_NAME); + } + return cb; +} + +DLLEXPORT void AudioEngine_unregister_me(void *hdl, void* cb) +{ + if (hdl && cb) + ((AddonCB*)hdl)->AudioEngineLib_UnRegisterMe(((AddonCB*)hdl)->addonData, (CB_AudioEngineLib*)cb); +} + +// --------------------------------------------- +// CAddonAEStream implementations +// --------------------------------------------- +DLLEXPORT CAddonAEStream* AudioEngine_make_stream(void *hdl, void *cb, AEDataFormat DataFormat, unsigned int SampleRate, unsigned int EncodedSampleRate, enum AEChannel *Channels, unsigned int Options) +{ + if (!hdl || !cb) + { + fprintf(stderr, "%s-ERROR: AudioEngine_register_me is called with NULL handle !!!\n", LIBRARY_NAME); + return NULL; + } + + AEStreamHandle *streamHandle = ((CB_AudioEngineLib*)cb)->MakeStream(DataFormat, SampleRate, EncodedSampleRate, Channels, Options); + if (!streamHandle) + { + fprintf(stderr, "%s-ERROR: AudioEngine_make_stream MakeStream failed!\n", LIBRARY_NAME); + return NULL; + } + + return new CAddonAEStream(hdl, cb, streamHandle); +} + +DLLEXPORT void AudioEngine_free_stream(CAddonAEStream *p) +{ + if (p) + { + delete p; + } +} + +DLLEXPORT bool AudioEngine_get_current_sink_Format(void *hdl, void *cb, AudioEngineFormat *SinkFormat) +{ + if (!cb) + { + return false; + } + + return ((CB_AudioEngineLib*)cb)->GetCurrentSinkFormat(((AddonCB*)hdl)->addonData, SinkFormat); +} + +CAddonAEStream::CAddonAEStream(void *Addon, void *Callbacks, AEStreamHandle *StreamHandle) +{ + m_AddonHandle = Addon; + m_Callbacks = Callbacks; + m_StreamHandle = StreamHandle; +} + +CAddonAEStream::~CAddonAEStream() +{ + if (m_StreamHandle) + { + ((CB_AudioEngineLib*)m_Callbacks)->FreeStream(m_StreamHandle); + m_StreamHandle = NULL; + } +} + +unsigned int CAddonAEStream::GetSpace() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetSpace(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +unsigned int CAddonAEStream::AddData(uint8_t* const *Data, unsigned int Offset, unsigned int Frames) +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_AddData(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle, Data, Offset, Frames); +} + +double CAddonAEStream::GetDelay() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetDelay(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +bool CAddonAEStream::IsBuffering() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_IsBuffering(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +double CAddonAEStream::GetCacheTime() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetCacheTime(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +double CAddonAEStream::GetCacheTotal() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetCacheTotal(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +void CAddonAEStream::Pause() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_Pause(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +void CAddonAEStream::Resume() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_Resume(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +void CAddonAEStream::Drain(bool Wait) +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_Drain(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle, Wait); +} + +bool CAddonAEStream::IsDraining() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_IsDraining(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +bool CAddonAEStream::IsDrained() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_IsDrained(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +void CAddonAEStream::Flush() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_Flush(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +float CAddonAEStream::GetVolume() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetVolume(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +void CAddonAEStream::SetVolume(float Volume) +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_SetVolume(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle, Volume); +} + +float CAddonAEStream::GetAmplification() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetAmplification(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +void CAddonAEStream::SetAmplification(float Amplify) +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_SetAmplification(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle, Amplify); +} + +const unsigned int CAddonAEStream::GetFrameSize() const +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetFrameSize(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +const unsigned int CAddonAEStream::GetChannelCount() const +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetChannelCount(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +const unsigned int CAddonAEStream::GetSampleRate() const +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetSampleRate(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +const unsigned int CAddonAEStream::GetEncodedSampleRate() const +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetEncodedSampleRate(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +const AEDataFormat CAddonAEStream::GetDataFormat() const +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetDataFormat(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +double CAddonAEStream::GetResampleRatio() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_GetResampleRatio(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} + +bool CAddonAEStream::SetResampleRatio(double Ratio) +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_SetResampleRatio(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle, Ratio); +} + +void CAddonAEStream::Discontinuity() +{ + return ((CB_AudioEngineLib*)m_Callbacks)->AEStream_Discontinuity(((AddonCB*)m_AddonHandle)->addonData, m_StreamHandle); +} +}; diff --git a/lib/addons/library.kodi.audioengine/project/VS2010Express/libKODI_audioengine.vcxproj b/lib/addons/library.kodi.audioengine/project/VS2010Express/libKODI_audioengine.vcxproj new file mode 100644 index 0000000000..e7077c6354 --- /dev/null +++ b/lib/addons/library.kodi.audioengine/project/VS2010Express/libKODI_audioengine.vcxproj @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\libKODI_audioengine.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\..\..\addons\library.kodi.audioengine\libKODI_audioengine.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6B96FD7D-26EE-415B-8858-27757A0B1273}</ProjectGuid> + <RootNamespace>KODI_ADSP</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(SolutionDir)\XBMC.core-defaults.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(SolutionDir)\XBMC.defaults.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\..\..\addons\library.kodi.audioengine\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\..\..\addons\library.kodi.audioengine\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\..\..\addons\library.xbmc.addon\;$(IncludePath)</IncludePath> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\..\..\addons\library.xbmc.addon\;$(IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>..\..\..\..\..\xbmc\;..\..\..\..\..\xbmc\addons\include\;..\..\..\..\..\addons\library.xbmc.addon\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;VDR_EXPORTS;_WIN32PC;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader> + </PrecompiledHeader> + </ClCompile> + <Link> + <OutputFile>..\..\..\..\..\addons\library.kodi.audioengine\$(ProjectName).dll</OutputFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>..\..\..\..\..\xbmc\;..\..\..\..\..\xbmc\addons\include\;..\..\..\..\..\addons\library.xbmc.addon\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;HAS_SDL_OPENGL;HAS_SDL;_USRDLL;XBMC_VDR_EXPORTS;_WIN32PC;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader> + </PrecompiledHeader> + </ClCompile> + <Link> + <OutputFile>..\..\..\..\..\addons\library.kodi.audioengine\$(ProjectName).dll</OutputFile> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/addons/library.kodi.audioengine/project/VS2010Express/libKODI_audioengine.vcxproj.filters b/lib/addons/library.kodi.audioengine/project/VS2010Express/libKODI_audioengine.vcxproj.filters new file mode 100644 index 0000000000..dc997c1497 --- /dev/null +++ b/lib/addons/library.kodi.audioengine/project/VS2010Express/libKODI_audioengine.vcxproj.filters @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{A463B136-5D8C-4995-A8D5-67FA2B90B6A8}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{EAFF7342-E9A9-4164-A40A-639A72C620DA}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\libKODI_audioengine.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\..\..\addons\library.kodi.audioengine\libKODI_audioengine.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/project/VS2010Express/XBMC for Windows.sln b/project/VS2010Express/XBMC for Windows.sln index b18090c0cb..6e09d41dfe 100644 --- a/project/VS2010Express/XBMC for Windows.sln +++ b/project/VS2010Express/XBMC for Windows.sln @@ -57,6 +57,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Effects11", "..\..\lib\win3 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libKODI_adsp", "..\..\lib\addons\library.kodi.adsp\project\VS2010Express\libKODI_adsp.vcxproj", "{44F93C4D-85DD-4452-99BB-F1D196174024}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libKODI_audioengine", "..\..\lib\addons\library.kodi.audioengine\project\VS2010Express\libKODI_audioengine.vcxproj", "{6B96FD7D-26EE-415B-8858-27757A0B1273}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug Testsuite|Win32 = Debug Testsuite|Win32 @@ -203,6 +205,12 @@ Global {44F93C4D-85DD-4452-99BB-F1D196174024}.Debug|Win32.Build.0 = Debug|Win32 {44F93C4D-85DD-4452-99BB-F1D196174024}.Release|Win32.ActiveCfg = Release|Win32 {44F93C4D-85DD-4452-99BB-F1D196174024}.Release|Win32.Build.0 = Release|Win32 + {6B96FD7D-26EE-415B-8858-27757A0B1273}.Debug Testsuite|Win32.ActiveCfg = Debug|Win32 + {6B96FD7D-26EE-415B-8858-27757A0B1273}.Debug Testsuite|Win32.Build.0 = Debug|Win32 + {6B96FD7D-26EE-415B-8858-27757A0B1273}.Debug|Win32.ActiveCfg = Debug|Win32 + {6B96FD7D-26EE-415B-8858-27757A0B1273}.Debug|Win32.Build.0 = Debug|Win32 + {6B96FD7D-26EE-415B-8858-27757A0B1273}.Release|Win32.ActiveCfg = Release|Win32 + {6B96FD7D-26EE-415B-8858-27757A0B1273}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 25f7419f65..c3f69a7d33 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -184,6 +184,7 @@ <ClCompile Include="..\..\xbmc\addons\AddonCallbacks.cpp" /> <ClCompile Include="..\..\xbmc\addons\AddonCallbacksAddon.cpp" /> <ClCompile Include="..\..\xbmc\addons\AddonCallbacksAudioDSP.cpp" /> + <ClCompile Include="..\..\xbmc\addons\AddonCallbacksAudioEngine.cpp" /> <ClCompile Include="..\..\xbmc\addons\AddonCallbacksCodec.cpp" /> <ClCompile Include="..\..\xbmc\addons\AddonCallbacksGUI.cpp" /> <ClCompile Include="..\..\xbmc\addons\AddonCallbacksPVR.cpp" /> @@ -888,6 +889,7 @@ <ClCompile Include="..\..\xbmc\TextureDatabase.cpp" /> <ClCompile Include="..\..\xbmc\DatabaseManager.cpp" /> <ClInclude Include="..\..\xbmc\addons\AddonCallbacksAudioDSP.h" /> + <ClInclude Include="..\..\xbmc\addons\AddonCallbacksAudioEngine.h" /> <ClInclude Include="..\..\xbmc\addons\AddonCallbacksCodec.h" /> <ClInclude Include="..\..\xbmc\addons\AudioDecoder.h" /> <ClInclude Include="..\..\xbmc\addons\ContextMenuAddon.h" /> @@ -908,6 +910,7 @@ <ClInclude Include="..\..\xbmc\cores\AudioEngine\DSPAddons\ActiveAEDSPDatabase.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\DSPAddons\ActiveAEDSPMode.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\DSPAddons\ActiveAEDSPProcess.h" /> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\Utils\AEStreamData.h" /> <ClInclude Include="..\..\xbmc\cores\DataCacheCore.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEFactory.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEResampleFactory.h" /> @@ -1324,7 +1327,6 @@ <ClCompile Include="..\..\xbmc\utils\AliasShortcutUtils.cpp" /> <ClCompile Include="..\..\xbmc\utils\Archive.cpp" /> <ClCompile Include="..\..\xbmc\utils\AsyncFileCopy.cpp" /> - <ClCompile Include="..\..\xbmc\utils\AutoPtrHandle.cpp" /> <ClCompile Include="..\..\xbmc\utils\Base64.cpp" /> <ClCompile Include="..\..\xbmc\utils\BitstreamStats.cpp" /> <ClCompile Include="..\..\xbmc\utils\CharsetConverter.cpp" /> @@ -2164,7 +2166,7 @@ <ClInclude Include="..\..\xbmc\utils\AliasShortcutUtils.h" /> <ClInclude Include="..\..\xbmc\utils\Archive.h" /> <ClInclude Include="..\..\xbmc\utils\AsyncFileCopy.h" /> - <ClInclude Include="..\..\xbmc\utils\AutoPtrHandle.h" /> + <ClInclude Include="..\..\xbmc\utils\ScopeGuard.h" /> <ClInclude Include="..\..\xbmc\utils\Base64.h" /> <ClInclude Include="..\..\xbmc\utils\BitstreamStats.h" /> <ClInclude Include="..\..\xbmc\utils\CharsetConverter.h" /> @@ -3007,4 +3009,4 @@ </VisualStudio> </ProjectExtensions> <Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" /> -</Project>
\ No newline at end of file +</Project> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index ba7cb91e68..4ed9479e11 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -1396,9 +1396,6 @@ <ClCompile Include="..\..\xbmc\utils\AsyncFileCopy.cpp"> <Filter>utils</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\utils\AutoPtrHandle.cpp"> - <Filter>utils</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\utils\BitstreamStats.cpp"> <Filter>utils</Filter> </ClCompile> @@ -3258,6 +3255,9 @@ <ClCompile Include="..\..\xbmc\interfaces\builtins\WeatherBuiltins.cpp"> <Filter>interfaces\builtins</Filter> </ClCompile> + <ClCompile Include="..\..\xbmc\addons\AddonCallbacksAudioEngine.cpp"> + <Filter>addons</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\xbmc\win32\pch.h"> @@ -4441,9 +4441,6 @@ <ClInclude Include="..\..\xbmc\utils\AsyncFileCopy.h"> <Filter>utils</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\utils\AutoPtrHandle.h"> - <Filter>utils</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\utils\BitstreamStats.h"> <Filter>utils</Filter> </ClInclude> @@ -6316,6 +6313,15 @@ <ClInclude Include="..\..\xbmc\interfaces\builtins\WeatherBuiltins.h"> <Filter>interfaces\builtins</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\addons\AddonCallbacksAudioEngine.h"> + <Filter>addons</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\cores\AudioEngine\Utils\AEStreamData.h"> + <Filter>cores\AudioEngine\Utils</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\utils\ScopeGuard.h"> + <Filter>utils</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc"> diff --git a/project/Win32BuildSetup/genNsisIncludes.bat b/project/Win32BuildSetup/genNsisIncludes.bat index ef01b27a23..5ccaef5c57 100644 --- a/project/Win32BuildSetup/genNsisIncludes.bat +++ b/project/Win32BuildSetup/genNsisIncludes.bat @@ -76,6 +76,22 @@ IF EXIST BUILD_WIN32\addons\adsp.* ( ) SET Counter=1 +IF EXIST BUILD_WIN32\addons\screensaver.* ( + ECHO SectionGroup "Screensaver Add-ons" SecScreensaverAddons >> screensaver-addons.nsi + FOR /F "tokens=*" %%P IN ('dir /B /AD BUILD_WIN32\addons\screensaver.*') DO ( + SET "output=%%P" + SET output=!output:screensaver.=! + ECHO Section "!output!" SecScreensaverAddons!Counter! >> screensaver-addons.nsi + ECHO SectionIn 1 2 3 #section is in installtype Full >> screensaver-addons.nsi + ECHO SetOutPath "$INSTDIR\addons\%%P" >> screensaver-addons.nsi + ECHO File /r "${app_root}\addons\%%P\*.*" >> screensaver-addons.nsi + ECHO SectionEnd >> screensaver-addons.nsi + SET /A Counter = !Counter! + 1 + ) + ECHO SectionGroupEnd >> screensaver-addons.nsi +) + +SET Counter=1 IF EXIST BUILD_WIN32\addons\visualization.* ( ECHO SectionGroup "Music Visualization Add-ons" SecVisualizationAddons >> visualization-addons.nsi FOR /F "tokens=*" %%P IN ('dir /B /AD BUILD_WIN32\addons\visualization.*') DO ( diff --git a/project/Win32BuildSetup/genNsisInstaller.nsi b/project/Win32BuildSetup/genNsisInstaller.nsi index 5603a47851..a3e2ac2c3d 100644 --- a/project/Win32BuildSetup/genNsisInstaller.nsi +++ b/project/Win32BuildSetup/genNsisInstaller.nsi @@ -283,6 +283,7 @@ SectionEnd !include /nonfatal "audiodsp-addons.nsi" !include /nonfatal "pvr-addons.nsi" !include /nonfatal "skin-addons.nsi" +!include /nonfatal "screensaver-addons.nsi" !include /nonfatal "visualization-addons.nsi" ;-------------------------------- diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 7457f634c7..a0e3f2d215 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -476,6 +476,11 @@ <default>false</default> <control type="toggle" /> </setting> + <setting id="videolibrary.groupsingleitemsets" type="boolean" label="20470" help="36157"> + <level>0</level> + <default>false</default> + <control type="toggle" /> + </setting> </group> <group id="2"> <setting id="videolibrary.updateonstartup" type="boolean" label="22000" help="36146"> diff --git a/system/shaders/testshader.fx b/system/shaders/testshader.fx index 8c41ee7edf..cefee8c983 100644 --- a/system/shaders/testshader.fx +++ b/system/shaders/testshader.fx @@ -27,6 +27,6 @@ technique11 TEST_T { pass P0 { - SetPixelShader( CompileShader( ps_4_0_level_9_3, TEST() ) ); + SetPixelShader( CompileShader( ps_4_0_level_9_1, TEST() ) ); } }; diff --git a/tools/buildsteps/android/package b/tools/buildsteps/android/package index cbbfb731c7..efcaab86fb 100644 --- a/tools/buildsteps/android/package +++ b/tools/buildsteps/android/package @@ -18,4 +18,4 @@ if [ -f *.obb ] then mv *.obb $UPLOAD_FILENAME.obb fi -mv tools/android/packaging/Kodi.symbols*.tar.bz2 $ANDROID_DEV_ROOT/debug-symbols/ +mv tools/android/packaging/Kodi.symbols*.tar.bz2 $WORKSPACE/ diff --git a/tools/buildsteps/androidx86/package b/tools/buildsteps/androidx86/package index f7fed28eec..212ffc3b39 100644 --- a/tools/buildsteps/androidx86/package +++ b/tools/buildsteps/androidx86/package @@ -18,3 +18,4 @@ if [ -f *.obb ] then mv *.obb $UPLOAD_FILENAME.obb fi +mv tools/android/packaging/Kodi.symbols*.tar.bz2 $WORKSPACE/ diff --git a/tools/darwin/Configurations/App-iOS.xcconfig b/tools/darwin/Configurations/App-iOS.xcconfig index ce7e788052..d31fb7173c 100644 --- a/tools/darwin/Configurations/App-iOS.xcconfig +++ b/tools/darwin/Configurations/App-iOS.xcconfig @@ -43,3 +43,6 @@ OTHER_CPLUSPLUSFLAGS = $(inherited) $(OTHER_CFLAGS) -Wreorder OTHER_LDFLAGS = $(XBMC_OTHER_LDFLAGS_COMMON) -weak_framework VideoToolbox GCC_PREPROCESSOR_DEFINITIONS = TARGET_DARWIN_IOS $(inherited) + +// set this to YES once we have a deployment target of at least ios 6.0 +ENABLE_BITCODE = NO diff --git a/tools/darwin/Configurations/App.xcconfig.in b/tools/darwin/Configurations/App.xcconfig.in index 1a1a2c00c7..fdf7ea5f7b 100644 --- a/tools/darwin/Configurations/App.xcconfig.in +++ b/tools/darwin/Configurations/App.xcconfig.in @@ -25,7 +25,7 @@ HEADER_SEARCH_PATHS = $(inherited) $SRCROOT xbmc xbmc/linux xbmc/osx xbmc/cores/ LIBRARY_SEARCH_PATHS = $(inherited) $(SRCROOT) $(SRCROOT)/xbmc/interfaces/json-rpc "$(SRCROOT)/xbmc/interfaces/python" "$(SRCROOT)/xbmc/interfaces/legacy" FRAMEWORK_SEARCH_PATHS = $(inherited) "$(SDKROOT)/System/Library/PrivateFrameworks/" "$(SDKROOT)/System/Library/Frameworks/" -XBMC_OTHER_LDFLAGS_COMMON = $(inherited) -Wl,-headerpad_max_install_names -Wl,-all_load -L$XBMC_DEPENDS/lib -lbz2 -lintl -lexpat -lssl -lgpg-error -lresolv -lffi -lssh -llzo2 -lpcre -lpcrecpp -lfribidi -lfreetype -lfontconfig -lsqlite3 -ltinyxml -lmicrohttpd -lsmbclient -lpython2.6 -lyajl -ljpeg -lcrypto -lgcrypt -lavdevice -lavfilter -lavcodec -lavformat -lpostproc -lavutil -ldcadec -lswresample -lswscale -ltag -L$XBMC_DEPENDS/lib/mysql -lmysqlclient -lxml2 -lxslt -lnettle -lgmp -lhogweed -lgnutls -lsquish -lcrossguid +XBMC_OTHER_LDFLAGS_COMMON = $(inherited) -Wl,-headerpad_max_install_names -Wl,-all_load -L$XBMC_DEPENDS/lib -lbz2 -lintl -lexpat -lssl -lgpg-error -lresolv -lffi -lssh -llzo2 -lpcre -lpcrecpp -lfribidi -lfreetype -lfontconfig -lsqlite3 -ltinyxml -lmicrohttpd -lsmbclient -lpython2.6 -lyajl -ljpeg -lcrypto -lgcrypt -lavdevice -lavfilter -lavcodec -lavformat -lpostproc -lavutil -ldcadec -lswresample -lswscale -ltag -L$XBMC_DEPENDS/lib/mysql -lmysqlclient -lxml2 -lxslt -lnettle -lgmp -lhogweed -lgnutls -lsquish -lcrossguid -lz -lm -liconv CLANG_CXX_LANGUAGE_STANDARD = c++0x CLANG_CXX_LIBRARY = libc++ diff --git a/tools/darwin/Support/Codesign.command b/tools/darwin/Support/Codesign.command index 6c2128db60..1535d767d4 100755 --- a/tools/darwin/Support/Codesign.command +++ b/tools/darwin/Support/Codesign.command @@ -1,6 +1,6 @@ #!/bin/bash -#this is the list of binaries we have to sign for beeing able to run un-jailbroken +#this is the list of binaries we have to sign for being able to run un-jailbroken LIST_BINARY_EXTENSIONS="dylib so 0 vis pvr" export CODESIGN_ALLOCATE=`xcodebuild -find codesign_allocate` @@ -28,7 +28,7 @@ if [ "${PLATFORM_NAME}" == "iphoneos" ]; then codesign -v -f -s "iPhone Developer" --entitlements "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/" #if user has set a code_sign_identity different from iPhone Developer we do a real codesign (for deployment on non-jailbroken devices) - if ! [ -z "${CODE_SIGN_IDENTITY}" ] && [ "${CODE_SIGN_IDENTITY}" != "iPhone Developer" ] && [ "${CODE_SIGN_IDENTITY}" != "Don't Code Sign" ]; then + if ! [ -z "${CODE_SIGN_IDENTITY}" ] && [ "${CODE_SIGN_IDENTITY}" == "iPhone Developer" ] && [ "${CODE_SIGN_IDENTITY}" != "Don't Code Sign" ]; then echo Doing a full bundle sign using genuine identity "${CODE_SIGN_IDENTITY}" for binext in $LIST_BINARY_EXTENSIONS do diff --git a/tools/depends/README b/tools/depends/README index 1db6a04494..398188bbee 100644 --- a/tools/depends/README +++ b/tools/depends/README @@ -29,3 +29,27 @@ Linux: Native toolchain ./configure --with-toolchain=/usr --prefix=/opt/xbmc-deps --host=x86_64-linux-gnu + +Details: + We build a native tools for platforms that do not have the native tools we need. OSX is + the largest builder of native tools as there is not much present. No cmake, no autotools, etc. + + Cross compiling is a real pain is the rear :) Generally there are three forms, + autotools (configure/make), cmake driven, and hand crafted makefile. In term + of usage, 90 percent are autotools, followed by cmake and hand crafted makefiles. + Some libs need patching, most do not. Lib versions are picked for a reason, be prepared + for robust testing if you go bumping libs. Never commit bumps unless you have also done + a complete distclean nuke of EVERYTHING and rebuild from scratch on ALL platforms. + Epic fail if this is not tested. + + 1) autotool driven tend to be simple PROVIDED the authors followed proper autotool format. + Try with $(CONFIGURE) 1st, if problem, try adding $(AUTORECONF) -vif before the + $(CONFIGURE). Some are do silly things and only a config.site can correct the errors. + So watch for this in the config.site.in. config.site rules and this is the only way + to handle bad autotool behavior. + + 2) cmake driven tend to be simple, setup cmake flags right and go. On rare cases, you might + need to diddle the native cmake setup. + + 3) hand crafted Makefiles typically require manual sed tweeks or patching. + diff --git a/tools/depends/configure.ac b/tools/depends/configure.ac index 9435fca7d1..815254e57b 100644 --- a/tools/depends/configure.ac +++ b/tools/depends/configure.ac @@ -227,6 +227,7 @@ case $host in 10.8);; 10.9);; 10.10);; + 10.11);; *) AC_MSG_ERROR(error in configure of --with-sdk=$use_sdk) esac @@ -277,6 +278,7 @@ case $host in 6.*);; 7.*);; 8.*);; + 9.*);; *) AC_MSG_ERROR(error in configure of --with-sdk=$use_sdk) ;; diff --git a/tools/depends/native/TexturePacker/src/configure.ac b/tools/depends/native/TexturePacker/src/configure.ac index a00ad023b5..a3e9f1e1be 100644 --- a/tools/depends/native/TexturePacker/src/configure.ac +++ b/tools/depends/native/TexturePacker/src/configure.ac @@ -19,7 +19,7 @@ AC_ARG_ENABLE([static], PKG_CHECK_MODULES([PNG], [libpng], - [INCLUDES="$PNG_CFLAGS"; LIBS="$LIBS $(pkg-config --silence-errors --static --libs libpng)"], + [INCLUDES="$PNG_CFLAGS"; LIBS="$LIBS $(${PKG_CONFIG} --silence-errors --static --libs libpng)"], AC_MSG_ERROR("libpng not found")) AC_CHECK_HEADER([gif_lib.h],, AC_MSG_ERROR("gif_lib.h not found")) diff --git a/tools/depends/native/cmake-native/Makefile b/tools/depends/native/cmake-native/Makefile index 45f1249a05..c673f87312 100644 --- a/tools/depends/native/cmake-native/Makefile +++ b/tools/depends/native/cmake-native/Makefile @@ -11,6 +11,11 @@ ARCHIVE=$(SOURCE).tar.gz SETENV=CC=$(CC_FOR_BUILD) CXX=$(CXX_FOR_BUILD) LD=$(LD_FOR_BUILD) CFLAGS=$(NATIVE_CFLAGS) \ CXXFLAGS=$(NATIVE_CXXFLAGS) LDFLAGS=$(NATIVE_LDFLAGS) + +ifeq ($(NATIVE_OS), osx) + SETENV+=SDKROOT=$(shell xcrun --show-sdk-path) +endif + CONFIGURE=./bootstrap --prefix=$(NATIVEPREFIX) --system-curl APP=$(PLATFORM)/bin/$(APPNAME) @@ -25,6 +30,7 @@ $(TARBALLS_LOCATION)/$(ARCHIVE): $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) -rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM) cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + cd $(PLATFORM); patch -p1 < ../darwin_enable_tbd_support.patch cd $(PLATFORM); $(SETENV) $(CONFIGURE) $(APP): $(PLATFORM) diff --git a/tools/depends/native/cmake-native/darwin_enable_tbd_support.patch b/tools/depends/native/cmake-native/darwin_enable_tbd_support.patch new file mode 100644 index 0000000000..031b5def8e --- /dev/null +++ b/tools/depends/native/cmake-native/darwin_enable_tbd_support.patch @@ -0,0 +1,14 @@ +diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake +index 4e4810a..bb085ac 100644 (file) +--- a/Modules/Platform/Darwin.cmake ++++ b/Modules/Platform/Darwin.cmake +@@ -53,7 +53,7 @@ set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_ + set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names") + set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") + set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") +-set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a") ++set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a") + + # hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old build tree + # (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache + diff --git a/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl b/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl index fbf08539fb..c5a71fb29d 100755 --- a/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl +++ b/tools/depends/native/gas-preprocessor-native/gas-preprocessor.pl @@ -63,7 +63,7 @@ while (@ARGV) { $force_thumb = 1; } elsif ($opt eq "-arch") { $arch = shift; - die "unknown arch: '$arch'\n" if not exists $comments{$arch}; + die "unknown arch: '$arch'\n" if not exists $canonical_arch{$arch}; } elsif ($opt eq "-as-type") { $as_type = shift; die "unknown as type: '$as_type'\n" if $as_type !~ /^((apple-)?(gas|clang)|armasm)$/; @@ -429,7 +429,7 @@ sub parse_line { sub handle_set { my $line = $_[0]; - if ($line =~ /\.set\s+(.*),\s*(.*)/) { + if ($line =~ /\.(?:set|equ)\s+(\S*)\s*,\s*(.*)/) { $symbols{$1} = eval_expr($2); return 1; } @@ -874,7 +874,7 @@ sub handle_serialized_line { # Don't interpret e.g. bic as b<cc> with ic as conditional code if ($cond !~ /|$arm_cond_codes/) { # Not actually a branch - } elsif ($target =~ /(\d+)([bf])/) { + } elsif ($target =~ /^(\d+)([bf])$/) { # The target is a local label $line = handle_local_label($line, $1, $2); $line =~ s/\b$instr\b/$&.w/ if $width eq ""; @@ -888,12 +888,12 @@ sub handle_serialized_line { } # ALIGN in armasm syntax is the actual number of bytes - if ($line =~ /\.align\s+(\d+)/) { + if ($line =~ /\.(?:p2)?align\s+(\d+)/) { my $align = 1 << $1; - $line =~ s/\.align\s(\d+)/ALIGN $align/; + $line =~ s/\.(?:p2)?align\s(\d+)/ALIGN $align/; } # Convert gas style [r0, :128] into armasm [r0@128] alignment specification - $line =~ s/\[([^\[]+),\s*:(\d+)\]/[$1\@$2]/g; + $line =~ s/\[([^\[,]+),?\s*:(\d+)\]/[$1\@$2]/g; # armasm treats logical values {TRUE} and {FALSE} separately from # numeric values - logical operators and values can't be intermixed @@ -930,7 +930,7 @@ sub handle_serialized_line { # Misc bugs/deficiencies: # armasm seems unable to parse e.g. "vmov s0, s1" without a type # qualifier, thus add .f32. - $line =~ s/^(\s+(?:vmov|vadd))(\s+s)/$1.f32$2/; + $line =~ s/^(\s+(?:vmov|vadd))(\s+s\d+\s*,\s*s\d+)/$1.f32$2/; # armasm is unable to parse &0x - add spacing $line =~ s/&0x/& 0x/g; } @@ -939,16 +939,17 @@ sub handle_serialized_line { # Convert register post indexing to a separate add instruction. # This converts e.g. "ldr r0, [r1], r2" into "ldr r0, [r1]", # "add r1, r1, r2". - $line =~ s/(ldr|str)\s+(\w+),\s*\[(\w+)\],\s*(\w+)/$1 $2, [$3]\n\tadd $3, $3, $4/g; + $line =~ s/((?:ldr|str)[bh]?)\s+(\w+),\s*\[(\w+)\],\s*(\w+)/$1 $2, [$3]\n\tadd $3, $3, $4/g; # Convert "mov pc, lr" into "bx lr", since the former only works # for switching from arm to thumb (and only in armv7), but not # from thumb to arm. s/mov\s*pc\s*,\s*lr/bx lr/g; - # Convert stmdb/ldmia with only one register into a plain str/ldr with post-increment/decrement - $line =~ s/stmdb\s+sp!\s*,\s*\{([^,-]+)\}/str $1, [sp, #-4]!/g; - $line =~ s/ldmia\s+sp!\s*,\s*\{([^,-]+)\}/ldr $1, [sp], #4/g; + # Convert stmdb/ldmia/stmfd/ldmfd/ldm with only one register into a plain str/ldr with post-increment/decrement. + # Wide thumb2 encoding requires at least two registers in register list while all other encodings support one register too. + $line =~ s/stm(?:db|fd)\s+sp!\s*,\s*\{([^,-]+)\}/str $1, [sp, #-4]!/g; + $line =~ s/ldm(?:ia|fd)?\s+sp!\s*,\s*\{([^,-]+)\}/ldr $1, [sp], #4/g; $line =~ s/\.arm/.thumb/x; } @@ -978,6 +979,9 @@ sub handle_serialized_line { $line =~ s/\.int/.long/x; $line =~ s/\.float/.single/x; } + if ($as_type eq "apple-gas") { + $line =~ s/vmrs\s+APSR_nzcv/fmrx r15/x; + } if ($as_type eq "armasm") { $line =~ s/\.global/EXPORT/x; $line =~ s/\.int/dcd/x; @@ -986,11 +990,15 @@ sub handle_serialized_line { $line =~ s/\.word/dcd/x; $line =~ s/\.short/dcw/x; $line =~ s/\.byte/dcb/x; + $line =~ s/\.quad/dcq/x; + $line =~ s/\.ascii/dcb/x; + $line =~ s/\.asciz(.*)$/dcb\1,0/x; $line =~ s/\.thumb/THUMB/x; $line =~ s/\.arm/ARM/x; # The alignment in AREA is the power of two, just as .align in gas - $line =~ s/\.text/AREA |.text|, CODE, READONLY, ALIGN=2, CODEALIGN/; + $line =~ s/\.text/AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN/; $line =~ s/(\s*)(.*)\.rodata/$1AREA |.rodata|, DATA, READONLY, ALIGN=5/; + $line =~ s/\.data/AREA |.data|, DATA, ALIGN=5/; $line =~ s/fmxr/vmsr/; $line =~ s/fmrx/vmrs/; diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile index edc7ab411e..d4a77aae52 100644 --- a/tools/depends/target/Makefile +++ b/tools/depends/target/Makefile @@ -86,7 +86,7 @@ python26: expat gettext libxml2 sqlite3 openssl libffi libcdio: $(ICONV) libplist: libxml2 $(ZLIB) libbluray: $(ICONV) libxml2 -libssh: openssl +libssh: openssl $(ZLIB) mysql: openssl libzip: $(ZLIB) libpng: $(ZLIB) diff --git a/tools/depends/target/libssh/Makefile b/tools/depends/target/libssh/Makefile index d7af794730..7fb244ecb4 100644 --- a/tools/depends/target/libssh/Makefile +++ b/tools/depends/target/libssh/Makefile @@ -23,7 +23,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) cd $(PLATFORM); patch -p0 < ../ntohl.patch cd $(PLATFORM); patch -p0 < ../md5.patch cd $(PLATFORM); patch -p1 < ../darwin.patch - sed -ie "s|-fstack-protector|-fnostack-protector|" "$(PLATFORM)/cmake/Modules/DefineCompilerFlags.cmake" + sed -ie "s|-fstack-protector|-fno-stack-protector|" "$(PLATFORM)/cmake/Modules/DefineCompilerFlags.cmake" sed -ie "s|add_subdirectory(examples)||" "$(PLATFORM)/CMakeLists.txt" cd $(PLATFORM)/build; $(CMAKE) -DWITH_STATIC_LIB=1 -DWITH_EXAMPLES=0 -DTHREADS_PTHREAD_ARG=0 -DWITH_GSSAPI=0 VERBOSE=1 .. @@ -34,6 +34,7 @@ $(LIBDYLIB): $(PLATFORM) make -C $(PLATFORM)/build install rm -f $(PREFIX)/lib/libssh.so $(PREFIX)/lib/libssh.so.4.3.0 $(PREFIX)/lib/libssh.so.4 rm -f $(PREFIX)/lib/libssh.*dylib* + rm -f $(PREFIX)/lib/libssh_threads.*dylib* touch $@ clean: diff --git a/tools/depends/target/samba-gplv3/Makefile b/tools/depends/target/samba-gplv3/Makefile index 19e4c808e0..dabedc4eb3 100644 --- a/tools/depends/target/samba-gplv3/Makefile +++ b/tools/depends/target/samba-gplv3/Makefile @@ -50,7 +50,8 @@ $(LIBDYLIB): $(PLATFORM) .installed-$(PLATFORM): $(LIBDYLIB) $(MAKE) -C $(PLATFORM)/source3 installlibsmbclient ifeq (darwin, $(findstring darwin, $(HOST))) - install_name_tool -id $(PREFIX)/lib/libsmbclient.dylib.0 $(PREFIX)/lib/libsmbclient.dylib.0 + mv $(PREFIX)/lib/libsmbclient.dylib.0 $(PREFIX)/lib/libsmbclient.dylib + install_name_tool -id $(PREFIX)/lib/libsmbclient.dylib $(PREFIX)/lib/libsmbclient.dylib endif ifeq ($(OS),android) rm -f $(PREFIX)/lib/libsmbclient.so diff --git a/xbmc/Autorun.cpp b/xbmc/Autorun.cpp index 5d8a33942c..1570f6401c 100644 --- a/xbmc/Autorun.cpp +++ b/xbmc/Autorun.cpp @@ -19,12 +19,12 @@ */ #include "system.h" -#include <utility> #ifdef HAS_DVD_DRIVE +#include "Autorun.h" + #include <stdlib.h> -#include "Autorun.h" #include "Application.h" #include "GUIPassword.h" #include "GUIUserMessages.h" @@ -46,6 +46,7 @@ #include "utils/URIUtils.h" #include "utils/log.h" #include "utils/Variant.h" + #ifdef HAS_CDDA_RIPPER #include "cdrip/CDDARipper.h" #endif diff --git a/xbmc/Autorun.h b/xbmc/Autorun.h index 37f8e6b752..8831a8e67f 100644 --- a/xbmc/Autorun.h +++ b/xbmc/Autorun.h @@ -33,6 +33,7 @@ #ifdef HAS_DVD_DRIVE #include <string> +#include <utility> #include <vector> namespace XFILE diff --git a/xbmc/ContextMenuManager.h b/xbmc/ContextMenuManager.h index 44bd288c81..d8c731611d 100644 --- a/xbmc/ContextMenuManager.h +++ b/xbmc/ContextMenuManager.h @@ -19,9 +19,11 @@ * */ +#include <utility> #include <vector> -#include "ContextMenuItem.h" + #include "addons/ContextMenuAddon.h" +#include "ContextMenuItem.h" #include "dialogs/GUIDialogContextMenu.h" diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 72f3ab0bf3..a51d9a3b01 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -24,17 +24,18 @@ * */ +#include <memory> +#include <utility> +#include <vector> + #include "guilib/GUIListItem.h" +#include "GUIPassword.h" +#include "threads/CriticalSection.h" #include "utils/IArchivable.h" #include "utils/ISerializable.h" #include "utils/ISortable.h" -#include "XBDateTime.h" #include "utils/SortUtils.h" -#include "GUIPassword.h" -#include "threads/CriticalSection.h" - -#include <vector> -#include <memory> +#include "XBDateTime.h" namespace MUSIC_INFO { diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index 26214ac00a..9ed84bc533 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -4365,6 +4365,14 @@ std::string CGUIInfoManager::GetVideoLabel(int item) } } } + else if (m_currentFile->HasPVRRecordingInfoTag()) + { + switch (item) + { + case VIDEOPLAYER_PLOT: + return m_currentFile->GetPVRRecordingInfoTag()->m_strPlot; + } + } else if (m_currentFile->HasVideoInfoTag()) { switch (item) @@ -5285,7 +5293,7 @@ std::string CGUIInfoManager::GetItemLabel(const CFileItem *item, int info, std:: return item->GetPVRTimerInfoTag()->GetEpgInfoTag()->Plot(); if (item->HasVideoInfoTag()) { - if (item->GetVideoInfoTag()->m_type != MediaTypeTvShow) + if (item->GetVideoInfoTag()->m_type != MediaTypeTvShow && item->GetVideoInfoTag()->m_type != MediaTypeVideoCollection) if (item->GetVideoInfoTag()->m_playCount == 0 && !CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOLIBRARY_SHOWUNWATCHEDPLOTS)) return g_localizeStrings.Get(20370); diff --git a/xbmc/GUILargeTextureManager.h b/xbmc/GUILargeTextureManager.h index 108cbdbad2..cc6cb3e897 100644 --- a/xbmc/GUILargeTextureManager.h +++ b/xbmc/GUILargeTextureManager.h @@ -20,9 +20,11 @@ * */ +#include <utility> + +#include "guilib/TextureManager.h" #include "threads/CriticalSection.h" #include "utils/Job.h" -#include "guilib/TextureManager.h" /*! \ingroup textures,jobs diff --git a/xbmc/LangInfo.cpp b/xbmc/LangInfo.cpp index 6b0289371d..2b058579c1 100644 --- a/xbmc/LangInfo.cpp +++ b/xbmc/LangInfo.cpp @@ -19,32 +19,31 @@ */ #include "LangInfo.h" -#include "Application.h" -#include "messaging/ApplicationMessenger.h" -#include "FileItem.h" -#include "Util.h" + +#include <algorithm> + #include "addons/AddonInstaller.h" #include "addons/AddonManager.h" #include "addons/LanguageResource.h" #include "addons/RepositoryUpdater.h" +#include "Application.h" +#include "FileItem.h" #include "guilib/LocalizeStrings.h" +#include "messaging/ApplicationMessenger.h" #include "pvr/PVRManager.h" #include "settings/AdvancedSettings.h" #include "settings/lib/Setting.h" #include "settings/Settings.h" +#include "Util.h" #include "utils/CharsetConverter.h" -#include "utils/log.h" #include "utils/LangCodeExpander.h" +#include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Weather.h" #include "utils/XBMCTinyXML.h" #include "utils/XMLUtils.h" -#include <algorithm> -#include <locale> -#include <utility> -#include <set> using namespace PVR; using namespace KODI::MESSAGING; diff --git a/xbmc/LangInfo.h b/xbmc/LangInfo.h index 585df24b6d..57ffb9e2c7 100644 --- a/xbmc/LangInfo.h +++ b/xbmc/LangInfo.h @@ -19,6 +19,14 @@ * */ +#include <locale> +#include <map> +#include <memory> +#include <set> +#include <string> +#include <utility> +#include <vector> + #include "settings/lib/ISettingCallback.h" #include "settings/lib/ISettingsHandler.h" #include "utils/GlobalsHandling.h" @@ -26,13 +34,6 @@ #include "utils/Speed.h" #include "utils/Temperature.h" -#include <map> -#include <memory> -#include <set> -#include <string> -#include <vector> -#include <locale> - #ifdef TARGET_WINDOWS #ifdef GetDateFormat #undef GetDateFormat diff --git a/xbmc/PartyModeManager.cpp b/xbmc/PartyModeManager.cpp index 8e150f85b6..bed6afd3b2 100644 --- a/xbmc/PartyModeManager.cpp +++ b/xbmc/PartyModeManager.cpp @@ -18,26 +18,27 @@ * */ +#include "PartyModeManager.h" + #include <algorithm> -#include "threads/SystemClock.h" -#include "PartyModeManager.h" -#include "PlayListPlayer.h" +#include "Application.h" +#include "dialogs/GUIDialogOK.h" +#include "dialogs/GUIDialogProgress.h" +#include "guilib/GUIWindowManager.h" +#include "GUIUserMessages.h" +#include "interfaces/AnnouncementManager.h" #include "music/MusicDatabase.h" #include "music/windows/GUIWindowMusicPlaylist.h" -#include "video/VideoDatabase.h" +#include "PlayListPlayer.h" +#include "playlists/PlayList.h" #include "playlists/SmartPlayList.h" #include "profiles/ProfilesManager.h" -#include "dialogs/GUIDialogProgress.h" -#include "GUIUserMessages.h" -#include "guilib/GUIWindowManager.h" -#include "dialogs/GUIDialogOK.h" -#include "playlists/PlayList.h" +#include "threads/SystemClock.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/Variant.h" -#include "Application.h" -#include "interfaces/AnnouncementManager.h" +#include "video/VideoDatabase.h" using namespace PLAYLIST; diff --git a/xbmc/PartyModeManager.h b/xbmc/PartyModeManager.h index 0982679c41..bfbd0a61ec 100644 --- a/xbmc/PartyModeManager.h +++ b/xbmc/PartyModeManager.h @@ -19,11 +19,11 @@ * */ +#include <memory> #include <string> +#include <utility> #include <vector> -#include <memory> - class CFileItem; typedef std::shared_ptr<CFileItem> CFileItemPtr; class CFileItemList; namespace PLAYLIST diff --git a/xbmc/TextureDatabase.cpp b/xbmc/TextureDatabase.cpp index 0c28abaa43..db372e9935 100644 --- a/xbmc/TextureDatabase.cpp +++ b/xbmc/TextureDatabase.cpp @@ -259,7 +259,7 @@ bool CTextureDatabase::GetCachedTexture(const std::string &url, CTextureDetails if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("SELECT id, cachedurl, lasthashcheck, imagehash, width, height FROM texture JOIN sizes ON (texture.id=sizes.idtexture AND sizes.size=1) WHERE url='%s'", url.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // have some information details.id = m_pDS->fv(0).get_asInt(); @@ -295,7 +295,7 @@ bool CTextureDatabase::GetTextures(CVariant &items, const Filter &filter) return false; sql = PrepareSQL(sql, !filter.fields.empty() ? filter.fields.c_str() : "*") + sqlFilter; - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(sql)) return false; while (!m_pDS->eof()) @@ -343,16 +343,16 @@ bool CTextureDatabase::AddCachedTexture(const std::string &url, const CTextureDe if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("DELETE FROM texture WHERE url='%s'", url.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); std::string date = details.updateable ? CDateTime::GetCurrentDateTime().GetAsDBDateTime() : ""; sql = PrepareSQL("INSERT INTO texture (id, url, cachedurl, imagehash, lasthashcheck) VALUES(NULL, '%s', '%s', '%s', '%s')", url.c_str(), details.file.c_str(), details.hash.c_str(), date.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); int textureID = (int)m_pDS->lastinsertid(); // set the size information sql = PrepareSQL("INSERT INTO sizes (idtexture, size, usecount, lastusetime, width, height) VALUES(%u, 1, 1, CURRENT_TIMESTAMP, %u, %u)", textureID, details.width, details.height); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } catch (...) { @@ -375,7 +375,7 @@ bool CTextureDatabase::ClearCachedTexture(int id, std::string &cacheFile) if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("select cachedurl from texture where id=%u", id); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // have some information @@ -383,7 +383,7 @@ bool CTextureDatabase::ClearCachedTexture(int id, std::string &cacheFile) m_pDS->close(); // remove it sql = PrepareSQL("delete from texture where id=%u", id); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); return true; } m_pDS->close(); @@ -413,7 +413,7 @@ std::string CTextureDatabase::GetTextureForPath(const std::string &url, const st return ""; std::string sql = PrepareSQL("select texture from path where url='%s' and type='%s'", url.c_str(), type.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // have some information @@ -441,19 +441,19 @@ void CTextureDatabase::SetTextureForPath(const std::string &url, const std::stri return; std::string sql = PrepareSQL("select id from path where url='%s' and type='%s'", url.c_str(), type.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // update int pathID = m_pDS->fv(0).get_asInt(); m_pDS->close(); sql = PrepareSQL("update path set texture='%s' where id=%u", texture.c_str(), pathID); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } else { // add the texture m_pDS->close(); sql = PrepareSQL("insert into path (id, url, type, texture) values(NULL, '%s', '%s', '%s')", url.c_str(), type.c_str(), texture.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } } catch (...) @@ -471,7 +471,7 @@ void CTextureDatabase::ClearTextureForPath(const std::string &url, const std::st if (NULL == m_pDS.get()) return; std::string sql = PrepareSQL("DELETE FROM path WHERE url='%s' and type='%s'", url.c_str(), type.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } catch (...) { diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp index 77c2db834c..a32431f8c2 100644 --- a/xbmc/addons/Addon.cpp +++ b/xbmc/addons/Addon.cpp @@ -19,14 +19,27 @@ */ #include "Addon.h" + +#include <string.h> +#include <ostream> +#include <utility> +#include <vector> + #include "AddonManager.h" #include "addons/Service.h" #include "ContextMenuManager.h" -#include "RepositoryUpdater.h" -#include "settings/Settings.h" #include "filesystem/Directory.h" #include "filesystem/File.h" +#include "RepositoryUpdater.h" +#include "settings/Settings.h" #include "system.h" +#include "URL.h" +#include "Util.h" +#include "utils/log.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include "utils/Variant.h" + #ifdef HAS_PYTHON #include "interfaces/python/XBPython.h" #endif @@ -36,15 +49,6 @@ #ifdef TARGET_FREEBSD #include "freebsd/FreeBSDGNUReplacements.h" #endif -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" -#include "utils/Variant.h" -#include "URL.h" -#include "Util.h" -#include <vector> -#include <string.h> -#include <ostream> using XFILE::CDirectory; using XFILE::CFile; diff --git a/xbmc/addons/AddonCallbacks.cpp b/xbmc/addons/AddonCallbacks.cpp index 2d03861e20..3153a52ea1 100644 --- a/xbmc/addons/AddonCallbacks.cpp +++ b/xbmc/addons/AddonCallbacks.cpp @@ -22,6 +22,7 @@ #include "AddonCallbacks.h" #include "AddonCallbacksAddon.h" #include "AddonCallbacksAudioDSP.h" +#include "AddonCallbacksAudioEngine.h" #include "AddonCallbacksCodec.h" #include "AddonCallbacksGUI.h" #include "AddonCallbacksPVR.h" @@ -37,6 +38,7 @@ CAddonCallbacks::CAddonCallbacks(CAddon* addon) m_callbacks = new AddonCB; m_helperAddon = NULL; m_helperADSP = NULL; + m_helperAudioEngine = NULL; m_helperGUI = NULL; m_helperPVR = NULL; m_helperCODEC = NULL; @@ -47,6 +49,8 @@ CAddonCallbacks::CAddonCallbacks(CAddon* addon) m_callbacks->AddOnLib_UnRegisterMe = CAddonCallbacks::AddOnLib_UnRegisterMe; m_callbacks->ADSPLib_RegisterMe = CAddonCallbacks::ADSPLib_RegisterMe; m_callbacks->ADSPLib_UnRegisterMe = CAddonCallbacks::ADSPLib_UnRegisterMe; + m_callbacks->AudioEngineLib_RegisterMe = CAddonCallbacks::AudioEngineLib_RegisterMe; + m_callbacks->AudioEngineLib_UnRegisterMe = CAddonCallbacks::AudioEngineLib_UnRegisterMe; m_callbacks->CODECLib_RegisterMe = CAddonCallbacks::CODECLib_RegisterMe; m_callbacks->CODECLib_UnRegisterMe = CAddonCallbacks::CODECLib_UnRegisterMe; m_callbacks->GUILib_RegisterMe = CAddonCallbacks::GUILib_RegisterMe; @@ -61,6 +65,8 @@ CAddonCallbacks::~CAddonCallbacks() m_helperAddon = NULL; delete m_helperADSP; m_helperADSP = NULL; + delete m_helperAudioEngine; + m_helperAudioEngine = NULL; delete m_helperCODEC; m_helperCODEC = NULL; delete m_helperGUI; @@ -124,6 +130,33 @@ void CAddonCallbacks::ADSPLib_UnRegisterMe(void *addonData, CB_ADSPLib *cbTable) addon->m_helperADSP = NULL; } +CB_AudioEngineLib* CAddonCallbacks::AudioEngineLib_RegisterMe(void *addonData) +{ + CAddonCallbacks* addon = (CAddonCallbacks*) addonData; + if (addon == NULL) + { + CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); + return NULL; + } + + addon->m_helperAudioEngine = new CAddonCallbacksAudioEngine(addon->m_addon); + return addon->m_helperAudioEngine->GetCallbacks(); +} + +void CAddonCallbacks::AudioEngineLib_UnRegisterMe(void *addonData, CB_AudioEngineLib *cbTable) +{ + CAddonCallbacks* addon = (CAddonCallbacks*) addonData; + if (addon == NULL) + { + CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); + return; + } + + delete addon->m_helperAudioEngine; + addon->m_helperAudioEngine = NULL; +} + + CB_CODECLib* CAddonCallbacks::CODECLib_RegisterMe(void *addonData) { CAddonCallbacks* addon = (CAddonCallbacks*) addonData; diff --git a/xbmc/addons/AddonCallbacks.h b/xbmc/addons/AddonCallbacks.h index 7c659c6666..daa3821fc3 100644 --- a/xbmc/addons/AddonCallbacks.h +++ b/xbmc/addons/AddonCallbacks.h @@ -23,8 +23,10 @@ #include "../../addons/library.kodi.guilib/libKODI_guilib.h" #include "../../addons/library.kodi.adsp/libKODI_adsp.h" +#include "../../addons/library.kodi.audioengine/libKODI_audioengine.h" #include "cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h" #include "addons/include/kodi_adsp_types.h" +#include "addons/include/kodi_audioengine_types.h" #include "addons/include/xbmc_pvr_types.h" #include "addons/include/xbmc_codec_types.h" @@ -397,6 +399,72 @@ typedef struct CB_ADSPLib ADSPSoundPlay_GetVolume SoundPlay_GetVolume; } CB_ADSPLib; +// --------------------------------------- +// libKODI_audioengine definitions +// --------------------------------------- +typedef AEStreamHandle* (*AudioEngine_MakeStream)(AEDataFormat DataFormat, unsigned int SampleRate, unsigned int EncodedSampleRate, enum AEChannel *ChannelLayout, unsigned int Options); +typedef void (*AudioEngine_FreeStream)(AEStreamHandle *stream); +typedef bool (*AudioEngine_GetCurrentSinkFormat)(void *addonData, AudioEngineFormat *SinkFormat); + +// Audio Engine Stream definitions +typedef unsigned int (*AudioEngine_Stream_GetSpace)(void *addonData, AEStreamHandle *handle); +typedef unsigned int (*AudioEngine_Stream_AddData)(void *addonData, AEStreamHandle *handle, uint8_t* const *Data, unsigned int Offset, unsigned int Frames); +typedef double (*AudioEngine_Stream_GetDelay)(void *addonData, AEStreamHandle *handle); +typedef bool (*AudioEngine_Stream_IsBuffering)(void *addonData, AEStreamHandle *handle); +typedef double (*AudioEngine_Stream_GetCacheTime)(void *addonData, AEStreamHandle *handle); +typedef double (*AudioEngine_Stream_GetCacheTotal)(void *addonData, AEStreamHandle *handle); +typedef void (*AudioEngine_Stream_Pause)(void *addonData, AEStreamHandle *handle); +typedef void (*AudioEngine_Stream_Resume)(void *addonData, AEStreamHandle *handle); +typedef void (*AudioEngine_Stream_Drain)(void *addonData, AEStreamHandle *handle, bool Wait); +typedef bool (*AudioEngine_Stream_IsDraining)(void *addonData, AEStreamHandle *handle); +typedef bool (*AudioEngine_Stream_IsDrained)(void *addonData, AEStreamHandle *handle); +typedef void (*AudioEngine_Stream_Flush)(void *addonData, AEStreamHandle *handle); +typedef float (*AudioEngine_Stream_GetVolume)(void *addonData, AEStreamHandle *handle); +typedef void (*AudioEngine_Stream_SetVolume)(void *addonData, AEStreamHandle *handle, float Volume); +typedef float (*AudioEngine_Stream_GetAmplification)(void *addonData, AEStreamHandle *handle); +typedef void (*AudioEngine_Stream_SetAmplification)(void *addonData, AEStreamHandle *handle, float Amplify); +typedef const unsigned int (*AudioEngine_Stream_GetFrameSize)(void *addonData, AEStreamHandle *handle); +typedef const unsigned int (*AudioEngine_Stream_GetChannelCount)(void *addonData, AEStreamHandle *handle); +typedef const unsigned int (*AudioEngine_Stream_GetSampleRate)(void *addonData, AEStreamHandle *handle); +typedef const unsigned int (*AudioEngine_Stream_GetEncodedSampleRate)(void *addonData, AEStreamHandle *handle); +typedef const AEDataFormat (*AudioEngine_Stream_GetDataFormat)(void *addonData, AEStreamHandle *handle); +typedef double (*AudioEngine_Stream_GetResampleRatio)(void *addonData, AEStreamHandle *handle); +typedef bool (*AudioEngine_Stream_SetResampleRatio)(void *addonData, AEStreamHandle *handle, double Ratio); +typedef void (*AudioEngine_Stream_Discontinuity)(void *addonData, AEStreamHandle *handle); + +typedef struct CB_AudioEngineLib +{ + AudioEngine_MakeStream MakeStream; + AudioEngine_FreeStream FreeStream; + AudioEngine_GetCurrentSinkFormat GetCurrentSinkFormat; + + // AudioEngine stream callbacks + AudioEngine_Stream_GetSpace AEStream_GetSpace; + AudioEngine_Stream_AddData AEStream_AddData; + AudioEngine_Stream_GetDelay AEStream_GetDelay; + AudioEngine_Stream_IsBuffering AEStream_IsBuffering; + AudioEngine_Stream_GetCacheTime AEStream_GetCacheTime; + AudioEngine_Stream_GetCacheTotal AEStream_GetCacheTotal; + AudioEngine_Stream_Pause AEStream_Pause; + AudioEngine_Stream_Resume AEStream_Resume; + AudioEngine_Stream_Drain AEStream_Drain; + AudioEngine_Stream_IsDraining AEStream_IsDraining; + AudioEngine_Stream_IsDrained AEStream_IsDrained; + AudioEngine_Stream_Flush AEStream_Flush; + AudioEngine_Stream_GetVolume AEStream_GetVolume; + AudioEngine_Stream_SetVolume AEStream_SetVolume; + AudioEngine_Stream_GetAmplification AEStream_GetAmplification; + AudioEngine_Stream_SetAmplification AEStream_SetAmplification; + AudioEngine_Stream_GetFrameSize AEStream_GetFrameSize; + AudioEngine_Stream_GetChannelCount AEStream_GetChannelCount; + AudioEngine_Stream_GetSampleRate AEStream_GetSampleRate; + AudioEngine_Stream_GetEncodedSampleRate AEStream_GetEncodedSampleRate; + AudioEngine_Stream_GetDataFormat AEStream_GetDataFormat; + AudioEngine_Stream_GetResampleRatio AEStream_GetResampleRatio; + AudioEngine_Stream_SetResampleRatio AEStream_SetResampleRatio; + AudioEngine_Stream_Discontinuity AEStream_Discontinuity; +} CB_AudioEngineLib; + typedef void (*PVRTransferEpgEntry)(void *userData, const ADDON_HANDLE handle, const EPG_TAG *epgentry); typedef void (*PVRTransferChannelEntry)(void *userData, const ADDON_HANDLE handle, const PVR_CHANNEL *chan); typedef void (*PVRTransferTimerEntry)(void *userData, const ADDON_HANDLE handle, const PVR_TIMER *timer); @@ -440,6 +508,8 @@ typedef CB_AddOnLib* (*XBMCAddOnLib_RegisterMe)(void *addonData); typedef void (*XBMCAddOnLib_UnRegisterMe)(void *addonData, CB_AddOnLib *cbTable); typedef CB_ADSPLib* (*KODIADSPLib_RegisterMe)(void *addonData); typedef void (*KODIADSPLib_UnRegisterMe)(void *addonData, CB_ADSPLib *cbTable); +typedef CB_AudioEngineLib* (*KODIAudioEngineLib_RegisterMe)(void *addonData); +typedef void (*KODIAudioEngineLib_UnRegisterMe)(void *addonData, CB_AudioEngineLib *cbTable); typedef CB_CODECLib* (*XBMCCODECLib_RegisterMe)(void *addonData); typedef void (*XBMCCODECLib_UnRegisterMe)(void *addonData, CB_CODECLib *cbTable); typedef CB_GUILib* (*XBMCGUILib_RegisterMe)(void *addonData); @@ -453,6 +523,8 @@ typedef struct AddonCB void *addonData; XBMCAddOnLib_RegisterMe AddOnLib_RegisterMe; XBMCAddOnLib_UnRegisterMe AddOnLib_UnRegisterMe; + KODIAudioEngineLib_RegisterMe AudioEngineLib_RegisterMe; + KODIAudioEngineLib_UnRegisterMe AudioEngineLib_UnRegisterMe; XBMCCODECLib_RegisterMe CODECLib_RegisterMe; XBMCCODECLib_UnRegisterMe CODECLib_UnRegisterMe; XBMCGUILib_RegisterMe GUILib_RegisterMe; @@ -470,6 +542,7 @@ namespace ADDON class CAddon; class CAddonCallbacksAddon; class CAddonCallbacksADSP; +class CAddonCallbacksAudioEngine; class CAddonCallbacksCodec; class CAddonCallbacksGUI; class CAddonCallbacksPVR; @@ -485,6 +558,8 @@ public: static void AddOnLib_UnRegisterMe(void *addonData, CB_AddOnLib *cbTable); static CB_ADSPLib* ADSPLib_RegisterMe(void *addonData); static void ADSPLib_UnRegisterMe(void *addonData, CB_ADSPLib *cbTable); + static CB_AudioEngineLib* AudioEngineLib_RegisterMe(void *addonData); + static void AudioEngineLib_UnRegisterMe(void *addonData, CB_AudioEngineLib *cbTable); static CB_CODECLib* CODECLib_RegisterMe(void *addonData); static void CODECLib_UnRegisterMe(void *addonData, CB_CODECLib *cbTable); static CB_GUILib* GUILib_RegisterMe(void *addonData); @@ -494,6 +569,7 @@ public: CAddonCallbacksAddon *GetHelperAddon() { return m_helperAddon; } CAddonCallbacksADSP *GetHelperADSP() { return m_helperADSP; } + CAddonCallbacksAudioEngine *GetHelperAudioEngine() { return m_helperAudioEngine; } CAddonCallbacksCodec *GetHelperCodec() { return m_helperCODEC; } CAddonCallbacksGUI *GetHelperGUI() { return m_helperGUI; } CAddonCallbacksPVR *GetHelperPVR() { return m_helperPVR; } @@ -503,6 +579,7 @@ private: CAddon *m_addon; CAddonCallbacksAddon *m_helperAddon; CAddonCallbacksADSP *m_helperADSP; + CAddonCallbacksAudioEngine *m_helperAudioEngine; CAddonCallbacksCodec *m_helperCODEC; CAddonCallbacksGUI *m_helperGUI; CAddonCallbacksPVR *m_helperPVR; diff --git a/xbmc/addons/AddonCallbacksAudioEngine.cpp b/xbmc/addons/AddonCallbacksAudioEngine.cpp new file mode 100644 index 0000000000..33734793e5 --- /dev/null +++ b/xbmc/addons/AddonCallbacksAudioEngine.cpp @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2014 Team KODI + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "AddonCallbacksAudioEngine.h" +#include "cores/AudioEngine/AEFactory.h" +#include "cores/AudioEngine/Interfaces/AEStream.h" +#include "cores/AudioEngine/Utils/AEChannelData.h" +#include "utils/log.h" +#include "include/kodi_audioengine_types.h" + +namespace ADDON +{ + +CAddonCallbacksAudioEngine::CAddonCallbacksAudioEngine(CAddon* addon) +{ + m_addon = addon; + m_callbacks = new CB_AudioEngineLib; + + // write KODI audio DSP specific add-on function addresses to callback table + m_callbacks->MakeStream = AudioEngine_MakeStream; + m_callbacks->FreeStream = AudioEngine_FreeStream; + m_callbacks->GetCurrentSinkFormat = AudioEngine_GetCurrentSinkFormat; + + // AEStream add-on function callback table + m_callbacks->AEStream_GetSpace = AEStream_GetSpace; + m_callbacks->AEStream_AddData = AEStream_AddData; + m_callbacks->AEStream_GetDelay = AEStream_GetDelay; + m_callbacks->AEStream_IsBuffering = AEStream_IsBuffering; + m_callbacks->AEStream_GetCacheTime = AEStream_GetCacheTime; + m_callbacks->AEStream_GetCacheTotal = AEStream_GetCacheTotal; + m_callbacks->AEStream_Pause = AEStream_Pause; + m_callbacks->AEStream_Resume = AEStream_Resume; + m_callbacks->AEStream_Drain = AEStream_Drain; + m_callbacks->AEStream_IsDraining = AEStream_IsDraining; + m_callbacks->AEStream_IsDrained = AEStream_IsDrained; + m_callbacks->AEStream_Flush = AEStream_Flush; + m_callbacks->AEStream_GetVolume = AEStream_GetVolume; + m_callbacks->AEStream_SetVolume = AEStream_SetVolume; + m_callbacks->AEStream_GetAmplification = AEStream_GetAmplification; + m_callbacks->AEStream_SetAmplification = AEStream_SetAmplification; + m_callbacks->AEStream_GetFrameSize = AEStream_GetFrameSize; + m_callbacks->AEStream_GetChannelCount = AEStream_GetChannelCount; + m_callbacks->AEStream_GetSampleRate = AEStream_GetSampleRate; + m_callbacks->AEStream_GetEncodedSampleRate = AEStream_GetEncodedSampleRate; + m_callbacks->AEStream_GetDataFormat = AEStream_GetDataFormat; + m_callbacks->AEStream_GetResampleRatio = AEStream_GetResampleRatio; + m_callbacks->AEStream_SetResampleRatio = AEStream_SetResampleRatio; + m_callbacks->AEStream_Discontinuity = AEStream_Discontinuity; +} + +AEStreamHandle* CAddonCallbacksAudioEngine::AudioEngine_MakeStream(AEDataFormat DataFormat, unsigned int SampleRate, unsigned int EncodedSampleRate, enum AEChannel *Channels, unsigned int Options) +{ + if (!Channels) + { + CLog::Log(LOGERROR, "CAddonCallbacksAudioEngine - %s - Invalid input! Channels is a NULL pointer!", __FUNCTION__); + return NULL; + } + + CAEChannelInfo channelInfo(Channels); + return CAEFactory::MakeStream(DataFormat, SampleRate, EncodedSampleRate, channelInfo, Options); +} + +void CAddonCallbacksAudioEngine::AudioEngine_FreeStream(AEStreamHandle *StreamHandle) +{ + if (!StreamHandle) + { + CLog::Log(LOGERROR, "CAddonCallbacksAudioEngine - %s - invalid stream data", __FUNCTION__); + return; + } + + CAEFactory::FreeStream((IAEStream*)StreamHandle); +} + +bool CAddonCallbacksAudioEngine::AudioEngine_GetCurrentSinkFormat(void *AddonData, AudioEngineFormat *SinkFormat) +{ + if (!AddonData || !SinkFormat) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid input data!", __FUNCTION__); + return false; + } + + AEAudioFormat AESinkFormat; + if (!CAEFactory::GetEngine() || !CAEFactory::GetEngine()->GetCurrentSinkFormat(AESinkFormat)) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - failed to get current sink format from AE!", __FUNCTION__); + return false; + } + + SinkFormat->m_channelCount = AESinkFormat.m_channelLayout.Count(); + for (int ch = 0; ch < SinkFormat->m_channelCount; ch++) + { + SinkFormat->m_channels[ch] = AESinkFormat.m_channelLayout[ch]; + } + + SinkFormat->m_dataFormat = AESinkFormat.m_dataFormat; + SinkFormat->m_sampleRate = AESinkFormat.m_sampleRate; + SinkFormat->m_encodedRate = AESinkFormat.m_encodedRate; + SinkFormat->m_frames = AESinkFormat.m_frames; + SinkFormat->m_frameSamples = AESinkFormat.m_frameSamples; + SinkFormat->m_frameSize = AESinkFormat.m_frameSize; + + return true; +} + +CAddonCallbacksAudioEngine::~CAddonCallbacksAudioEngine() +{ + /* delete the callback table */ + delete m_callbacks; +} + +unsigned int CAddonCallbacksAudioEngine::AEStream_GetSpace(void *AddonData, AEStreamHandle *StreamHandle) +{ + if (!AddonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return 0; + } + + return ((IAEStream*)StreamHandle)->GetSpace(); +} + +unsigned int CAddonCallbacksAudioEngine::AEStream_AddData(void *AddonData, AEStreamHandle *StreamHandle, uint8_t* const *Data, unsigned int Offset, unsigned int Frames) +{ + if (!AddonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return 0; + } + + return ((IAEStream*)StreamHandle)->AddData(Data, Offset, Frames); +} + +double CAddonCallbacksAudioEngine::AEStream_GetDelay(void *AddonData, AEStreamHandle *StreamHandle) +{ + if (!AddonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return -1.0; + } + + return ((IAEStream*)StreamHandle)->GetDelay(); +} + +bool CAddonCallbacksAudioEngine::AEStream_IsBuffering(void *AddonData, AEStreamHandle *StreamHandle) +{ + if (!AddonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return false; + } + + return ((IAEStream*)StreamHandle)->IsBuffering(); +} + +double CAddonCallbacksAudioEngine::AEStream_GetCacheTime(void *AddonData, AEStreamHandle *StreamHandle) +{ + if (!AddonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return -1.0; + } + + return ((IAEStream*)StreamHandle)->GetCacheTime(); +} + +double CAddonCallbacksAudioEngine::AEStream_GetCacheTotal(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return -1.0; + } + + return ((IAEStream*)StreamHandle)->GetCacheTotal(); +} + +void CAddonCallbacksAudioEngine::AEStream_Pause(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return; + } + + ((IAEStream*)StreamHandle)->Pause(); +} + +void CAddonCallbacksAudioEngine::AEStream_Resume(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return; + } + + ((IAEStream*)StreamHandle)->Resume(); +} + +void CAddonCallbacksAudioEngine::AEStream_Drain(void *AddonData, AEStreamHandle *StreamHandle, bool Wait) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return; + } + + ((IAEStream*)StreamHandle)->Drain(Wait); +} + +bool CAddonCallbacksAudioEngine::AEStream_IsDraining(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return false; + } + + return ((IAEStream*)StreamHandle)->IsDraining(); +} + +bool CAddonCallbacksAudioEngine::AEStream_IsDrained(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return false; + } + + return ((IAEStream*)StreamHandle)->IsDrained(); +} + +void CAddonCallbacksAudioEngine::AEStream_Flush(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return; + } + + ((IAEStream*)StreamHandle)->Flush(); +} + +float CAddonCallbacksAudioEngine::AEStream_GetVolume(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return -1.0f; + } + + return ((IAEStream*)StreamHandle)->GetVolume(); +} + +void CAddonCallbacksAudioEngine::AEStream_SetVolume(void *AddonData, AEStreamHandle *StreamHandle, float Volume) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return; + } + + ((IAEStream*)StreamHandle)->SetVolume(Volume); +} + +float CAddonCallbacksAudioEngine::AEStream_GetAmplification(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return -1.0f; + } + + return ((IAEStream*)StreamHandle)->GetAmplification(); +} + +void CAddonCallbacksAudioEngine::AEStream_SetAmplification(void *AddonData, AEStreamHandle *StreamHandle, float Amplify) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return; + } + + ((IAEStream*)StreamHandle)->SetAmplification(Amplify); +} + +const unsigned int CAddonCallbacksAudioEngine::AEStream_GetFrameSize(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return 0; + } + + return ((IAEStream*)StreamHandle)->GetFrameSize(); +} + +const unsigned int CAddonCallbacksAudioEngine::AEStream_GetChannelCount(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return 0; + } + + return ((IAEStream*)StreamHandle)->GetChannelCount(); +} + +const unsigned int CAddonCallbacksAudioEngine::AEStream_GetSampleRate(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return 0; + } + + return ((IAEStream*)StreamHandle)->GetSampleRate(); +} + +const unsigned int CAddonCallbacksAudioEngine::AEStream_GetEncodedSampleRate(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return 0; + } + + return ((IAEStream*)StreamHandle)->GetEncodedSampleRate(); +} + +const AEDataFormat CAddonCallbacksAudioEngine::AEStream_GetDataFormat(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return AE_FMT_INVALID; + } + + return ((IAEStream*)StreamHandle)->GetDataFormat(); +} + +double CAddonCallbacksAudioEngine::AEStream_GetResampleRatio(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return -1.0f; + } + + return ((IAEStream*)StreamHandle)->GetResampleRatio(); +} + +bool CAddonCallbacksAudioEngine::AEStream_SetResampleRatio(void *AddonData, AEStreamHandle *StreamHandle, double Ratio) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return false; + } + + return ((IAEStream*)StreamHandle)->SetResampleRatio(Ratio); +} + +void CAddonCallbacksAudioEngine::AEStream_Discontinuity(void *AddonData, AEStreamHandle *StreamHandle) +{ + // prevent compiler warnings + void *addonData = AddonData; + if (!addonData || !StreamHandle) + { + CLog::Log(LOGERROR, "libKODI_audioengine - %s - invalid stream data", __FUNCTION__); + return; + } + + ((IAEStream*)StreamHandle)->Discontinuity(); +} + +}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksAudioEngine.h b/xbmc/addons/AddonCallbacksAudioEngine.h new file mode 100644 index 0000000000..4facdfcfb7 --- /dev/null +++ b/xbmc/addons/AddonCallbacksAudioEngine.h @@ -0,0 +1,220 @@ +#pragma once +/* + * Copyright (C) 2014 Team KODI + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "AddonCallbacks.h" +#include "include/kodi_audioengine_types.h" + +namespace ADDON +{ + +/*! + * Callbacks for Kodi's AudioEngine. + */ +class CAddonCallbacksAudioEngine +{ +public: + CAddonCallbacksAudioEngine(CAddon* Addon); + ~CAddonCallbacksAudioEngine(); + + /*! + * @return The callback table. + */ + CB_AudioEngineLib *GetCallbacks() { return m_callbacks; } + + /** + * Creates and returns a new handle to an IAEStream in the format specified, this function should never fail + * @param dataFormat The data format the incoming audio will be in (eg, AE_FMT_S16LE) + * @param sampleRate The sample rate of the audio data (eg, 48000) + * @prarm encodedSampleRate The sample rate of the encoded audio data if AE_IS_RAW(dataFormat) + * @param channelLayout The order of the channels in the audio data + * @param options A bit field of stream options (see: enum AEStreamOptions) + * @return a new Handle to an IAEStream that will accept data in the requested format + */ + static AEStreamHandle* AudioEngine_MakeStream(AEDataFormat DataFormat, unsigned int SampleRate, unsigned int EncodedSampleRate, enum AEChannel *Channels, unsigned int Options); + + /** + * This method will remove the specifyed stream from the engine. + * For OSX/IOS this is essential to reconfigure the audio output. + * @param stream The stream to be altered + * @return NULL + */ + static void AudioEngine_FreeStream(AEStreamHandle *StreamHandle); + + /** + * Get the current sink data format + * + * @param Current sink data format. For more details see AudioEngineFormat. + * @return Returns true on success, else false. + */ + static bool AudioEngine_GetCurrentSinkFormat(void *AddonData, AudioEngineFormat *SinkFormat); + + /** + * Returns the amount of space available in the stream + * @return The number of bytes AddData will consume + */ + static unsigned int AEStream_GetSpace(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Add planar or interleaved PCM data to the stream + * @param data array of pointers to the planes + * @param offset to frame in frames + * @param frames number of frames + * @param pts timestamp + * @return The number of frames consumed + */ + static unsigned int AEStream_AddData(void *AddonData, AEStreamHandle *StreamHandle, uint8_t* const *Data, unsigned int Offset, unsigned int Frames); + + /** + * Returns the time in seconds that it will take + * for the next added packet to be heard from the speakers. + * @return seconds + */ + static double AEStream_GetDelay(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Returns if the stream is buffering + * @return True if the stream is buffering + */ + static bool AEStream_IsBuffering(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Returns the time in seconds that it will take + * to underrun the cache if no sample is added. + * @return seconds + */ + static double AEStream_GetCacheTime(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Returns the total time in seconds of the cache + * @return seconds + */ + static double AEStream_GetCacheTotal(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Pauses the stream playback + */ + static void AEStream_Pause(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Resumes the stream after pausing + */ + static void AEStream_Resume(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Start draining the stream + * @note Once called AddData will not consume more data. + */ + static void AEStream_Drain(void *AddonData, AEStreamHandle *StreamHandle, bool Wait); + + /** + * Returns true if the is stream draining + */ + static bool AEStream_IsDraining(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Returns true if the is stream has finished draining + */ + static bool AEStream_IsDrained(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Flush all buffers dropping the audio data + */ + static void AEStream_Flush(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Return the stream's current volume level + * @return The volume level between 0.0 and 1.0 + */ + static float AEStream_GetVolume(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Set the stream's volume level + * @param volume The new volume level between 0.0 and 1.0 + */ + static void AEStream_SetVolume(void *AddonData, AEStreamHandle *StreamHandle, float Volume); + + /** + * Gets the stream's volume amplification in linear units. + * @return The volume amplification factor between 1.0 and 1000.0 + */ + static float AEStream_GetAmplification(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Sets the stream's volume amplification in linear units. + * @param The volume amplification factor between 1.0 and 1000.0 + */ + static void AEStream_SetAmplification(void *AddonData, AEStreamHandle *StreamHandle, float Amplify); + + /** + * Returns the size of one audio frame in bytes (channelCount * resolution) + * @return The size in bytes of one frame + */ + static const unsigned int AEStream_GetFrameSize(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Returns the number of channels the stream is configured to accept + * @return The channel count + */ + static const unsigned int AEStream_GetChannelCount(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Returns the stream's sample rate, if the stream is using a dynamic sample rate, this value will NOT reflect any changes made by calls to SetResampleRatio() + * @return The stream's sample rate (eg, 48000) + */ + static const unsigned int AEStream_GetSampleRate(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Returns the stream's encoded sample rate if the stream is RAW + * @return The stream's encoded sample rate + */ + static const unsigned int AEStream_GetEncodedSampleRate(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Return the data format the stream has been configured with + * @return The stream's data format (eg, AE_FMT_S16LE) + */ + static const AEDataFormat AEStream_GetDataFormat(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Return the resample ratio + * @note This will return an undefined value if the stream is not resampling + * @return the current resample ratio or undefined if the stream is not resampling + */ + static double AEStream_GetResampleRatio(void *AddonData, AEStreamHandle *StreamHandle); + + /** + * Sets the resample ratio + * @note This function may return false if the stream is not resampling, if you wish to use this be sure to set the AESTREAM_FORCE_RESAMPLE option + * @param ratio the new sample rate ratio, calculated by ((double)desiredRate / (double)GetSampleRate()) + */ + static bool AEStream_SetResampleRatio(void *AddonData, AEStreamHandle *StreamHandle, double Ratio); + + /** + * Sginal a clock change + */ + static void AEStream_Discontinuity(void *AddonData, AEStreamHandle *StreamHandle); + +private: + CB_AudioEngineLib *m_callbacks; /*!< callback addresses */ + CAddon *m_addon; /*!< the addon */ +}; + +}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksCodec.cpp b/xbmc/addons/AddonCallbacksCodec.cpp index 5af953a277..17e5d2148b 100644 --- a/xbmc/addons/AddonCallbacksCodec.cpp +++ b/xbmc/addons/AddonCallbacksCodec.cpp @@ -19,6 +19,9 @@ */ #include "Addon.h" + +#include <utility> + #include "AddonCallbacksCodec.h" #include "utils/StringUtils.h" @@ -26,6 +29,7 @@ extern "C" { #include "libavcodec/avcodec.h" } + namespace ADDON { class CCodecIds diff --git a/xbmc/addons/AddonCallbacksGUI.cpp b/xbmc/addons/AddonCallbacksGUI.cpp index efc36fef59..9649311109 100644 --- a/xbmc/addons/AddonCallbacksGUI.cpp +++ b/xbmc/addons/AddonCallbacksGUI.cpp @@ -2179,12 +2179,8 @@ CGUIAddonWindowDialog::~CGUIAddonWindowDialog(void) bool CGUIAddonWindowDialog::OnMessage(CGUIMessage &message) { if (message.GetMessage() == GUI_MSG_WINDOW_DEINIT) - { - CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow()); - if (pWindow) - g_windowManager.ShowOverlay(pWindow->GetOverlayState()); return CGUIWindow::OnMessage(message); - } + return CGUIAddonWindow::OnMessage(message); } diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp index a0029e7866..c1ff8c49e9 100644 --- a/xbmc/addons/AddonDatabase.cpp +++ b/xbmc/addons/AddonDatabase.cpp @@ -19,12 +19,16 @@ */ #include "AddonDatabase.h" + +#include <utility> + #include "addons/AddonManager.h" +#include "dbwrappers/dataset.h" #include "utils/log.h" -#include "utils/Variant.h" #include "utils/StringUtils.h" +#include "utils/Variant.h" #include "XBDateTime.h" -#include "dbwrappers/dataset.h" + using namespace ADDON; @@ -141,23 +145,23 @@ int CAddonDatabase::AddAddon(const AddonPtr& addon, addon->ID().c_str(), addon->Version().asString().c_str(), addon->Author().c_str(),addon->Disclaimer().c_str(), addon->MinVersion().asString().c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); int idAddon = (int)m_pDS->lastinsertid(); sql = PrepareSQL("insert into addonlinkrepo (idRepo, idAddon) values (%i,%i)",idRepo,idAddon); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); const InfoMap &info = addon->ExtraInfo(); for (InfoMap::const_iterator i = info.begin(); i != info.end(); ++i) { sql = PrepareSQL("insert into addonextra(id, key, value) values (%i, '%s', '%s')", idAddon, i->first.c_str(), i->second.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } const ADDONDEPS &deps = addon->GetDeps(); for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i) { sql = PrepareSQL("insert into dependencies(id, addon, version, optional) values (%i, '%s', '%s', %i)", idAddon, i->first.c_str(), i->second.first.asString().c_str(), i->second.second ? 1 : 0); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } return idAddon; } @@ -180,7 +184,7 @@ AddonVersion CAddonDatabase::GetAddonVersion(const std::string &id) // so we want to retrieve the latest version. Order by version won't work as the database // won't know that 1.10 > 1.2, so grab them all and order outside std::string sql = PrepareSQL("select version from addon where addonID='%s'",id.c_str()); - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); if (m_pDS2->eof()) return maxversion; @@ -201,6 +205,67 @@ AddonVersion CAddonDatabase::GetAddonVersion(const std::string &id) return maxversion; } +bool CAddonDatabase::GetAvailableVersions(const std::string& addonId, + std::vector<std::pair<ADDON::AddonVersion, std::string>>& versionsInfo) +{ + try + { + if (NULL == m_pDB.get()) return false; + if (NULL == m_pDS.get()) return false; + + std::string sql = PrepareSQL( + "SELECT addon.version, repo.addonID AS repoID FROM addon " + "JOIN addonlinkrepo ON addonlinkrepo.idAddon=addon.id " + "JOIN repo ON repo.id=addonlinkrepo.idRepo " + "WHERE NOT EXISTS (SELECT * FROM disabled WHERE disabled.addonID=repoID) " + "AND NOT EXISTS (SELECT * FROM broken WHERE broken.addonID=addon.addonID) " + "AND addon.addonID='%s'", addonId.c_str()); + + m_pDS->query(sql.c_str()); + while (!m_pDS->eof()) + { + AddonVersion version(m_pDS->fv(0).get_asString()); + std::string repo = m_pDS->fv(1).get_asString(); + versionsInfo.push_back(std::make_pair(version, repo)); + m_pDS->next(); + } + return true; + } + catch (...) + { + CLog::Log(LOGERROR, "%s failed on addon %s", __FUNCTION__, addonId.c_str()); + } + return false; +} + +bool CAddonDatabase::GetAddon(const std::string& addonID, const AddonVersion& version, const std::string& repoId, AddonPtr& addon) +{ + try + { + if (NULL == m_pDB.get()) return false; + if (NULL == m_pDS.get()) return false; + + std::string sql = PrepareSQL( + "SELECT addon.id, addon.addonID, repo.addonID AS repoID FROM addon " + "JOIN addonlinkrepo ON addonlinkrepo.idAddon=addon.id " + "JOIN repo ON repo.id=addonlinkrepo.idRepo " + "WHERE addon.addonID='%s' AND addon.version='%s' AND repoID='%s'", + addonID.c_str(), version.asString().c_str(), repoId.c_str()); + + m_pDS->query(sql.c_str()); + if (m_pDS->eof()) + return false; + + return GetAddon(m_pDS->fv(0).get_asInt(), addon); + } + catch (...) + { + CLog::Log(LOGERROR, "%s failed on addon %s", __FUNCTION__, addonID.c_str()); + } + return false; + +} + bool CAddonDatabase::GetAddon(const std::string& id, AddonPtr& addon) { try @@ -212,7 +277,7 @@ bool CAddonDatabase::GetAddon(const std::string& id, AddonPtr& addon) // so we want to retrieve the latest version. Order by version won't work as the database // won't know that 1.10 > 1.2, so grab them all and order outside std::string sql = PrepareSQL("select id,version from addon where addonID='%s'",id.c_str()); - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); if (m_pDS2->eof()) return false; @@ -239,29 +304,6 @@ bool CAddonDatabase::GetAddon(const std::string& id, AddonPtr& addon) return false; } -bool CAddonDatabase::GetRepoForAddon(const std::string& addonID, std::string& repo) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS2.get()) return false; - - std::string sql = PrepareSQL("select repo.addonID from repo join addonlinkrepo on repo.id=addonlinkrepo.idRepo join addon on addonlinkrepo.idAddon=addon.id where addon.addonID like '%s'", addonID.c_str()); - m_pDS2->query(sql.c_str()); - if (!m_pDS2->eof()) - { - repo = m_pDS2->fv(0).get_asString(); - m_pDS2->close(); - return true; - } - } - catch (...) - { - CLog::Log(LOGERROR, "%s failed for addon %s", __FUNCTION__, addonID.c_str()); - } - return false; -} - bool CAddonDatabase::GetAddon(int id, AddonPtr &addon) { try @@ -283,7 +325,7 @@ bool CAddonDatabase::GetAddon(int id, AddonPtr &addon) sql += PrepareSQL(" WHERE addon.id=%i", id); - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); if (!m_pDS2->eof()) { const dbiplus::query_data &data = m_pDS2->get_result_set().records; @@ -347,7 +389,7 @@ bool CAddonDatabase::GetAddons(VECADDONS& addons, const ADDON::TYPE &type /* = A sql += PrepareSQL(" AND a.type = '%s'", strType.c_str()); } - m_pDS->query(sql.c_str()); + m_pDS->query(sql); while (!m_pDS->eof()) { AddonPtr addon; @@ -373,7 +415,7 @@ void CAddonDatabase::DeleteRepository(const std::string& id) if (NULL == m_pDS.get()) return; std::string sql = PrepareSQL("select id from repo where addonID='%s'",id.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) DeleteRepository(m_pDS->fv(0).get_asInt()); } @@ -391,15 +433,15 @@ void CAddonDatabase::DeleteRepository(int idRepo) if (NULL == m_pDS.get()) return; std::string sql = PrepareSQL("delete from repo where id=%i",idRepo); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); sql = PrepareSQL("delete from addon where id in (select idAddon from addonlinkrepo where idRepo=%i)",idRepo); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); sql = PrepareSQL("delete from addonextra where id in (select idAddon from addonlinkrepo where idRepo=%i)",idRepo); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); sql = PrepareSQL("delete from dependencies where id in (select idAddon from addonlinkrepo where idRepo=%i)",idRepo); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); sql = PrepareSQL("delete from addonlinkrepo where idRepo=%i",idRepo); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } catch (...) @@ -420,12 +462,15 @@ int CAddonDatabase::AddRepository(const std::string& id, const VECADDONS& addons if (idRepo > -1) DeleteRepository(idRepo); + if (!SetLastChecked(id, version, CDateTime::GetCurrentDateTime().GetAsDBDateTime())) + return -1; + BeginTransaction(); - CDateTime time = CDateTime::GetCurrentDateTime(); - sql = PrepareSQL("insert into repo (id,addonID,checksum,lastcheck,version) values (NULL,'%s','%s','%s','%s')", - id.c_str(), checksum.c_str(), time.GetAsDBDateTime().c_str(), version.asString().c_str()); - m_pDS->exec(sql.c_str()); + sql = PrepareSQL("UPDATE repo SET checksum='%s', version='%s' WHERE addonID='%s'", + checksum.c_str(), version.asString().c_str(), id.c_str()); + + m_pDS->exec(sql); idRepo = (int)m_pDS->lastinsertid(); for (unsigned int i=0;i<addons.size();++i) AddAddon(addons[i],idRepo); @@ -449,7 +494,7 @@ int CAddonDatabase::GetRepoChecksum(const std::string& id, std::string& checksum if (NULL == m_pDS.get()) return -1; std::string strSQL = PrepareSQL("select * from repo where addonID='%s'",id.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (!m_pDS->eof()) { checksum = m_pDS->fv("checksum").get_asString(); @@ -473,7 +518,7 @@ std::pair<CDateTime, ADDON::AddonVersion> CAddonDatabase::LastChecked(const std: if (m_pDB.get() != nullptr && m_pDS.get() != nullptr) { std::string strSQL = PrepareSQL("select * from repo where addonID='%s'",id.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (!m_pDS->eof()) { date.SetFromDBDateTime(m_pDS->fv("lastcheck").get_asString()); @@ -497,10 +542,17 @@ bool CAddonDatabase::SetLastChecked(const std::string& id, if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; - std::string sql = PrepareSQL("UPDATE repo SET lastcheck='%s', version='%s' WHERE addonID='%s'", - time.c_str(), version.asString().c_str(), id.c_str()); - m_pDS->exec(sql.c_str()); + std::string sql = PrepareSQL("SELECT * FROM repo WHERE addonID='%s'", id.c_str()); + m_pDS->query(sql); + + if (m_pDS->eof()) + sql = PrepareSQL("INSERT INTO repo (id, addonID, lastcheck, version) " + "VALUES (NULL, '%s', '%s', '%s')", id.c_str(), time.c_str(), version.asString().c_str()); + else + sql = PrepareSQL("UPDATE repo SET lastcheck='%s', version='%s' WHERE addonID='%s'", + time.c_str(), version.asString().c_str(), id.c_str()); + m_pDS->exec(sql); return true; } catch (...) @@ -519,16 +571,20 @@ bool CAddonDatabase::GetRepositoryContent(const std::string& id, VECADDONS& addo std::string query = PrepareSQL("select id from repo where addonID='%s'" " AND checksum != '' and lastcheck != ''", id.c_str()); - m_pDS->query(query.c_str()); + m_pDS->query(query); if (m_pDS->eof()) return false; - query = PrepareSQL("select * from addonlinkrepo where idRepo=%i", m_pDS->fv(0).get_asInt()); - m_pDS->query(query.c_str()); + query = PrepareSQL("SELECT addon.id FROM addon " + "JOIN addonlinkrepo ON addonlinkrepo.idAddon=addon.id " + "WHERE addonlinkrepo.idRepo=%i GROUP BY addon.addonID", + m_pDS->fv(0).get_asInt()); + + m_pDS->query(query); while (!m_pDS->eof()) { AddonPtr addon; - if (GetAddon(m_pDS->fv("idAddon").get_asInt(), addon)) + if (GetAddon(m_pDS->fv(0).get_asInt(), addon)) addons.push_back(addon); m_pDS->next(); } @@ -552,7 +608,7 @@ bool CAddonDatabase::Search(const std::string& search, VECADDONS& addons) strSQL=PrepareSQL("SELECT addonID FROM addon WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%'", search.c_str(), search.c_str(), search.c_str()); CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) return false; while (!m_pDS->eof()) @@ -655,7 +711,7 @@ bool CAddonDatabase::IsAddonDisabled(const std::string &addonID) if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("select id from disabled where addonID='%s'", addonID.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); bool ret = !m_pDS->eof(); // in the disabled table -> disabled m_pDS->close(); return ret; @@ -675,7 +731,7 @@ bool CAddonDatabase::GetDisabled(std::vector<std::string>& addons) if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("SELECT addonID FROM disabled"); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); while (!m_pDS->eof()) { addons.push_back(m_pDS->fv(0).get_asString()); @@ -723,6 +779,11 @@ bool CAddonDatabase::HasDisabledAddons() return false; } +bool CAddonDatabase::BlacklistAddon(const std::string& addonID) +{ + return BlacklistAddon(addonID, ""); +} + bool CAddonDatabase::BlacklistAddon(const std::string& addonID, const std::string& version) { @@ -731,7 +792,8 @@ bool CAddonDatabase::BlacklistAddon(const std::string& addonID, if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; - std::string sql = PrepareSQL("insert into blacklist(id, addonID, version) values(NULL, '%s', '%s')", addonID.c_str(),version.c_str()); + std::string sql = PrepareSQL("INSERT OR REPLACE INTO blacklist(id, addonID, version) " + "VALUES(NULL, '%s', '%s')", addonID.c_str(), version.c_str()); m_pDS->exec(sql); return true; @@ -746,10 +808,15 @@ bool CAddonDatabase::BlacklistAddon(const std::string& addonID, bool CAddonDatabase::IsAddonBlacklisted(const std::string& addonID, const std::string& version) { - std::string where = PrepareSQL("addonID='%s' and version='%s'",addonID.c_str(),version.c_str()); + std::string where = PrepareSQL("addonID='%s' and (version='%s' OR version='')",addonID.c_str(),version.c_str()); return !GetSingleValue("blacklist","addonID",where).empty(); } +bool CAddonDatabase::RemoveAddonFromBlacklist(const std::string& addonID) +{ + return RemoveAddonFromBlacklist(addonID, ""); +} + bool CAddonDatabase::RemoveAddonFromBlacklist(const std::string& addonID, const std::string& version) { @@ -829,7 +896,7 @@ bool CAddonDatabase::IsSystemAddonRegistered(const std::string &addonID) return false; std::string sql = PrepareSQL("select id from system where addonID='%s'", addonID.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); bool ret = !m_pDS->eof(); m_pDS->close(); return ret; diff --git a/xbmc/addons/AddonDatabase.h b/xbmc/addons/AddonDatabase.h index 2249c4ea0c..0ba71a5814 100644 --- a/xbmc/addons/AddonDatabase.h +++ b/xbmc/addons/AddonDatabase.h @@ -19,10 +19,12 @@ * */ -#include "dbwrappers/Database.h" +#include <string> +#include <vector> + #include "addons/Addon.h" +#include "dbwrappers/Database.h" #include "FileItem.h" -#include <string> class CAddonDatabase : public CDatabase { @@ -34,20 +36,21 @@ public: int GetAddonId(const ADDON::AddonPtr& item); int AddAddon(const ADDON::AddonPtr& item, int idRepo); bool GetAddon(const std::string& addonID, ADDON::AddonPtr& addon); + + /*! \brief Get an addon with a specific version and repository. */ + bool GetAddon(const std::string& addonID, const ADDON::AddonVersion& version, const std::string& repoId, ADDON::AddonPtr& addon); + bool GetAddons(ADDON::VECADDONS& addons, const ADDON::TYPE &type = ADDON::ADDON_UNKNOWN); /*! Get the addon IDs that has been set to disabled */ bool GetDisabled(std::vector<std::string>& addons); + bool GetAvailableVersions(const std::string& addonId, + std::vector<std::pair<ADDON::AddonVersion, std::string>>& versionsInfo); + /*! \brief grab the (largest) add-on version for an add-on */ ADDON::AddonVersion GetAddonVersion(const std::string &id); - /*! \brief Grab the repository from which a given addon came - \param addonID - the id of the addon in question - \param repo [out] - the id of the repository - \return true if a repo was found, false otherwise. - */ - bool GetRepoForAddon(const std::string& addonID, std::string& repo); int AddRepository(const std::string& id, const ADDON::VECADDONS& addons, const std::string& checksum, const ADDON::AddonVersion& version); void DeleteRepository(const std::string& id); void DeleteRepository(int id); @@ -113,8 +116,10 @@ public: \sa BreakAddon */ std::string IsAddonBroken(const std::string &addonID); + bool BlacklistAddon(const std::string& addonID); bool BlacklistAddon(const std::string& addonID, const std::string& version); bool IsAddonBlacklisted(const std::string& addonID, const std::string& version); + bool RemoveAddonFromBlacklist(const std::string& addonID); bool RemoveAddonFromBlacklist(const std::string& addonID, const std::string& version); diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp index 76eeace881..ceb5ec29c4 100644 --- a/xbmc/addons/AddonInstaller.cpp +++ b/xbmc/addons/AddonInstaller.cpp @@ -74,11 +74,7 @@ CAddonInstaller &CAddonInstaller::GetInstance() void CAddonInstaller::OnJobComplete(unsigned int jobID, bool success, CJob* job) { - if (success) - CAddonMgr::GetInstance().FindAddons(); - CSingleLock lock(m_critSection); - JobMap::iterator i = find_if(m_downloadJobs.begin(), m_downloadJobs.end(), bind2nd(find_map(), jobID)); if (i != m_downloadJobs.end()) m_downloadJobs.erase(i); @@ -195,21 +191,45 @@ bool CAddonInstaller::InstallOrUpdate(const std::string &addonID, bool backgroun CAddonMgr::GetInstance().GetAddon(addonID, addon, ADDON_UNKNOWN, false); // check whether we have it available in a repository + RepositoryPtr repo; + if (!GetRepoForAddon(addonID, repo)) + return false; + std::string hash; - if (!CAddonInstallJob::GetAddonWithHash(addonID, addon, hash)) + if (!CAddonInstallJob::GetAddonWithHash(addonID, repo->ID(), addon, hash)) return false; - return DoInstall(addon, hash, background, modal); + return DoInstall(addon, repo, hash, background, modal); +} + +void CAddonInstaller::Install(const std::string& addonId, const AddonVersion& version, const std::string& repoId) +{ + CLog::Log(LOGDEBUG, "CAddonInstaller: intalling '%s' version '%s' from repository '%s'", + addonId.c_str(), version.asString().c_str(), repoId.c_str()); + + AddonPtr addon; + CAddonDatabase database; + + if (!database.Open() || !database.GetAddon(addonId, version, repoId, addon)) + return; + + AddonPtr repo; + if (!CAddonMgr::GetInstance().GetAddon(repoId, repo, ADDON_REPOSITORY)) + return; + + std::string hash = std::static_pointer_cast<CRepository>(repo)->GetAddonHash(addon); + DoInstall(addon, std::static_pointer_cast<CRepository>(repo), hash, true, false); } -bool CAddonInstaller::DoInstall(const AddonPtr &addon, const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */) +bool CAddonInstaller::DoInstall(const AddonPtr &addon, const RepositoryPtr& repo, + const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */) { // check whether we already have the addon installing CSingleLock lock(m_critSection); if (m_downloadJobs.find(addon->ID()) != m_downloadJobs.end()) return false; - CAddonInstallJob* installJob = new CAddonInstallJob(addon, hash); + CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, hash); if (background) { unsigned int jobID = CJobManager::GetInstance().AddJob(installJob, this); @@ -264,7 +284,7 @@ bool CAddonInstaller::InstallFromZip(const std::string &path) addon->Props().icon = URIUtils::AddFileToFolder(items[0]->GetPath(), "icon.png"); // install the addon - return DoInstall(addon); + return DoInstall(addon, RepositoryPtr()); } CEventLog::GetInstance().AddWithNotification( @@ -414,6 +434,26 @@ void CAddonInstaller::InstallUpdates() } } +bool CAddonInstaller::GetRepoForAddon(const std::string& addonId, RepositoryPtr& repoPtr) +{ + CAddonDatabase database; + if (!database.Open()) + return false; + + std::vector<std::pair<ADDON::AddonVersion, std::string>> versions; + if (!database.GetAvailableVersions(addonId, versions) || versions.empty()) + return false; + + auto repoId = std::min_element(versions.begin(), versions.end())->second; + + AddonPtr tmp; + if (!CAddonMgr::GetInstance().GetAddon(repoId, tmp, ADDON_REPOSITORY)) + return false; + + repoPtr = std::static_pointer_cast<CRepository>(tmp); + return true; +} + int64_t CAddonInstaller::EnumeratePackageFolder(std::map<std::string,CFileItemList*>& result) { CFileItemList items; @@ -435,39 +475,16 @@ int64_t CAddonInstaller::EnumeratePackageFolder(std::map<std::string,CFileItemLi return size; } -CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const std::string &hash /* = "" */) +CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const AddonPtr &repo, const std::string &hash /* = "" */) : m_addon(addon), + m_repo(repo), m_hash(hash) { AddonPtr dummy; m_update = CAddonMgr::GetInstance().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN, false); } -AddonPtr CAddonInstallJob::GetRepoForAddon(const AddonPtr& addon) -{ - AddonPtr repoPtr; - - CAddonDatabase database; - if (!database.Open()) - return repoPtr; - - std::string repo; - if (!database.GetRepoForAddon(addon->ID(), repo)) - return repoPtr; - - if (!CAddonMgr::GetInstance().GetAddon(repo, repoPtr)) - return repoPtr; - - if (std::dynamic_pointer_cast<CRepository>(repoPtr) == NULL) - { - repoPtr.reset(); - return repoPtr; - } - - return repoPtr; -} - -bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, ADDON::AddonPtr& addon, std::string& hash) +bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, const std::string& repoID, ADDON::AddonPtr& addon, std::string& hash) { CAddonDatabase database; if (!database.Open()) @@ -476,15 +493,11 @@ bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, ADDON::Addon if (!database.GetAddon(addonID, addon)) return false; - AddonPtr ptr = GetRepoForAddon(addon); - if (ptr == NULL) - return false; - - RepositoryPtr repo = std::dynamic_pointer_cast<CRepository>(ptr); - if (repo == NULL) + AddonPtr repo; + if (!CAddonMgr::GetInstance().GetAddon(repoID, repo, ADDON_REPOSITORY)) return false; - hash = repo->GetAddonHash(addon); + hash = std::static_pointer_cast<CRepository>(repo)->GetAddonHash(addon); return true; } @@ -504,9 +517,8 @@ bool CAddonInstallJob::DoWork() return false; } - AddonPtr repoPtr = GetRepoForAddon(m_addon); std::string installFrom; - if (!repoPtr || repoPtr->Props().libname.empty()) + if (!m_repo || m_repo->Props().libname.empty()) { // Addons are installed by downloading the .zip package on the server to the local // packages folder, then extracting from the local .zip package into the addons folder @@ -590,16 +602,19 @@ bool CAddonInstallJob::DoWork() installFrom = archivedFiles[0]->GetPath(); } - repoPtr.reset(); + m_repo.reset(); } // run any pre-install functions ADDON::OnPreInstall(m_addon); // perform install - if (!Install(installFrom, repoPtr)) + if (!Install(installFrom, m_repo)) return false; + CAddonMgr::GetInstance().UnregisterAddon(m_addon->ID()); + CAddonMgr::GetInstance().FindAddons(); + // run any post-install guff CEventLog::GetInstance().Add( EventPtr(new CAddonManagementEvent(m_addon, m_update ? 24065 : 24064)), @@ -717,16 +732,18 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& r // don't have the addon or the addon isn't new enough - grab it (no new job for these) else if (IsModal()) { + RepositoryPtr repoForDep; AddonPtr addon; std::string hash; - if (!CAddonInstallJob::GetAddonWithHash(addonID, addon, hash)) + if (!CAddonInstaller::GetRepoForAddon(addonID, repoForDep) || + !CAddonInstallJob::GetAddonWithHash(addonID, repoForDep->ID(), addon, hash)) { CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to find dependency %s", m_addon->ID().c_str(), addonID.c_str()); ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); return false; } - CAddonInstallJob dependencyJob(addon, hash); + CAddonInstallJob dependencyJob(addon, repoForDep, hash); // pass our progress indicators to the temporary job and don't allow it to // show progress or information updates (no progress, title or text changes) @@ -790,9 +807,6 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& r ReportInstallError(addonID, addonID); return false; } - - // Update the addon manager so that it has the newly installed add-on. - CAddonMgr::GetInstance().FindAddons(); } SetProgress(100); @@ -846,12 +860,13 @@ bool CAddonUnInstallJob::DoWork() { ADDON::OnPreUnInstall(m_addon); - AddonPtr repoPtr = CAddonInstallJob::GetRepoForAddon(m_addon); - RepositoryPtr therepo = std::dynamic_pointer_cast<CRepository>(repoPtr); - if (therepo != NULL && !therepo->Props().libname.empty()) + //TODO: looks broken. it just calls the repo with the most recent version, not the owner + RepositoryPtr repoPtr; + CAddonInstaller::GetRepoForAddon(m_addon->ID(), repoPtr); + if (repoPtr != NULL && !repoPtr->Props().libname.empty()) { CFileItemList dummy; - std::string s = StringUtils::Format("plugin://%s/?action=uninstall&package=%s", therepo->ID().c_str(), m_addon->ID().c_str()); + std::string s = StringUtils::Format("plugin://%s/?action=uninstall&package=%s", repoPtr->ID().c_str(), m_addon->ID().c_str()); if (!CDirectory::GetDirectory(s, dummy)) return false; } diff --git a/xbmc/addons/AddonInstaller.h b/xbmc/addons/AddonInstaller.h index 533259600e..89073c04b7 100644 --- a/xbmc/addons/AddonInstaller.h +++ b/xbmc/addons/AddonInstaller.h @@ -19,11 +19,13 @@ * */ -#include "utils/FileOperationJob.h" +#include <utility> + #include "addons/Addon.h" #include "addons/Repository.h" -#include "utils/Stopwatch.h" #include "threads/Event.h" +#include "utils/FileOperationJob.h" +#include "utils/Stopwatch.h" class CAddonDatabase; @@ -69,6 +71,9 @@ public: */ bool InstallFromZip(const std::string &path); + /*! Install an addon with a specific version and repository */ + void Install(const std::string& addonId, const ADDON::AddonVersion& version, const std::string& repoId); + /*! \brief Check whether dependencies of an addon exist or are installable. Iterates through the addon's dependencies, checking they're installed or installable. Each dependency must also satisfies CheckDependencies in turn. @@ -99,6 +104,12 @@ public: void OnJobComplete(unsigned int jobID, bool success, CJob* job); void OnJobProgress(unsigned int jobID, unsigned int progress, unsigned int total, const CJob *job); + /*! \brief Get the repository which hosts the most recent version of add-on + * \param addon The add-on to find the repository for + * \param repo [out] The hosting repository + */ + static bool GetRepoForAddon(const std::string& addonId, ADDON::RepositoryPtr& repo); + class CDownloadJob { public: @@ -122,11 +133,13 @@ private: /*! \brief Install an addon from a repository or zip \param addon the AddonPtr describing the addon + \param repo the repository to install addon from \param hash the hash to verify the install. Defaults to "". \param background whether to install in the background or not. Defaults to true. \return true on successful install, false on failure. */ - bool DoInstall(const ADDON::AddonPtr &addon, const std::string &hash = "", bool background = true, bool modal = false); + bool DoInstall(const ADDON::AddonPtr &addon, const ADDON::RepositoryPtr &repo, + const std::string &hash = "", bool background = true, bool modal = false); /*! \brief Check whether dependencies of an addon exist or are installable. Iterates through the addon's dependencies, checking they're installed or installable. @@ -149,23 +162,17 @@ private: class CAddonInstallJob : public CFileOperationJob { public: - CAddonInstallJob(const ADDON::AddonPtr &addon, const std::string &hash = ""); + CAddonInstallJob(const ADDON::AddonPtr &addon, const ADDON::AddonPtr &repo, const std::string &hash = ""); virtual bool DoWork(); - /*! \brief Find which repository hosts an add-on - * \param addon The add-on to find the repository for - * \return The hosting repository - */ - static ADDON::AddonPtr GetRepoForAddon(const ADDON::AddonPtr& addon); - /*! \brief Find the add-on and itshash for the given add-on ID * \param addonID ID of the add-on to find * \param addon Add-on with the given add-on ID * \param hash Hash of the add-on * \return True if the add-on and its hash were found, false otherwise. */ - static bool GetAddonWithHash(const std::string& addonID, ADDON::AddonPtr& addon, std::string& hash); + static bool GetAddonWithHash(const std::string& addonID, const std::string &repoID, ADDON::AddonPtr& addon, std::string& hash); private: void OnPreInstall(); @@ -188,6 +195,7 @@ private: void ReportInstallError(const std::string& addonID, const std::string& fileName, const std::string& message = ""); ADDON::AddonPtr m_addon; + ADDON::AddonPtr m_repo; std::string m_hash; bool m_update; }; diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp index 07617e9b82..afcd9bea96 100644 --- a/xbmc/addons/AddonManager.cpp +++ b/xbmc/addons/AddonManager.cpp @@ -17,47 +17,51 @@ * <http://www.gnu.org/licenses/>. * */ -#include <memory> + #include "AddonManager.h" + +#include <memory> +#include <utility> + #include "Addon.h" -#include "AudioEncoder.h" -#include "AudioDecoder.h" -#include "ContextMenuManager.h" -#include "DllLibCPluff.h" #include "addons/ImageResource.h" #include "addons/LanguageResource.h" #include "addons/UISoundsResource.h" -#include "events/EventLog.h" +#include "addons/Webinterface.h" +#include "AudioDecoder.h" +#include "AudioEncoder.h" +#include "ContextMenuAddon.h" +#include "ContextMenuManager.h" +#include "cores/AudioEngine/DSPAddons/ActiveAEDSP.h" +#include "DllAudioDSP.h" +#include "DllLibCPluff.h" #include "events/AddonManagementEvent.h" -#include "utils/StringUtils.h" -#include "utils/JobManager.h" -#include "threads/SingleLock.h" +#include "events/EventLog.h" #include "LangInfo.h" +#include "PluginSource.h" +#include "Repository.h" +#include "Scraper.h" +#include "Service.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" +#include "Skin.h" +#include "system.h" +#include "threads/SingleLock.h" +#include "Util.h" +#include "utils/JobManager.h" #include "utils/log.h" +#include "utils/StringUtils.h" #include "utils/XBMCTinyXML.h" + #ifdef HAS_VISUALISATION #include "Visualisation.h" #endif #ifdef HAS_SCREENSAVER #include "ScreenSaver.h" #endif -#include "DllAudioDSP.h" -#include "cores/AudioEngine/DSPAddons/ActiveAEDSP.h" #ifdef HAS_PVRCLIENTS #include "pvr/addons/PVRClient.h" #endif -//#ifdef HAS_SCRAPERS -#include "Scraper.h" -//#endif -#include "PluginSource.h" -#include "Repository.h" -#include "Skin.h" -#include "Service.h" -#include "ContextMenuAddon.h" -#include "Util.h" -#include "addons/Webinterface.h" using namespace XFILE; @@ -594,29 +598,38 @@ bool CAddonMgr::SetDefault(const TYPE &type, const std::string &addonID) switch (type) { case ADDON_VIZ: - CSettings::GetInstance().SetString(CSettings::SETTING_MUSICPLAYER_VISUALISATION,addonID); + CSettings::GetInstance().SetString(CSettings::SETTING_MUSICPLAYER_VISUALISATION, addonID); break; case ADDON_SCREENSAVER: - CSettings::GetInstance().SetString(CSettings::SETTING_SCREENSAVER_MODE,addonID); + CSettings::GetInstance().SetString(CSettings::SETTING_SCREENSAVER_MODE, addonID); break; case ADDON_SCRAPER_ALBUMS: - CSettings::GetInstance().SetString(CSettings::SETTING_MUSICLIBRARY_ALBUMSSCRAPER,addonID); + CSettings::GetInstance().SetString(CSettings::SETTING_MUSICLIBRARY_ALBUMSSCRAPER, addonID); break; case ADDON_SCRAPER_ARTISTS: - CSettings::GetInstance().SetString(CSettings::SETTING_MUSICLIBRARY_ARTISTSSCRAPER,addonID); + CSettings::GetInstance().SetString(CSettings::SETTING_MUSICLIBRARY_ARTISTSSCRAPER, addonID); break; case ADDON_SCRAPER_MOVIES: - CSettings::GetInstance().SetString(CSettings::SETTING_SCRAPERS_MOVIESDEFAULT,addonID); + CSettings::GetInstance().SetString(CSettings::SETTING_SCRAPERS_MOVIESDEFAULT, addonID); break; case ADDON_SCRAPER_MUSICVIDEOS: - CSettings::GetInstance().SetString(CSettings::SETTING_SCRAPERS_MUSICVIDEOSDEFAULT,addonID); + CSettings::GetInstance().SetString(CSettings::SETTING_SCRAPERS_MUSICVIDEOSDEFAULT, addonID); break; case ADDON_SCRAPER_TVSHOWS: - CSettings::GetInstance().SetString(CSettings::SETTING_SCRAPERS_TVSHOWSDEFAULT,addonID); + CSettings::GetInstance().SetString(CSettings::SETTING_SCRAPERS_TVSHOWSDEFAULT, addonID); break; case ADDON_RESOURCE_LANGUAGE: CSettings::GetInstance().SetString(CSettings::SETTING_LOCALE_LANGUAGE, addonID); break; + case ADDON_SCRIPT_WEATHER: + CSettings::GetInstance().SetString(CSettings::SETTING_WEATHER_ADDON, addonID); + break; + case ADDON_SKIN: + CSettings::GetInstance().SetString(CSettings::SETTING_LOOKANDFEEL_SKIN, addonID); + break; + case ADDON_RESOURCE_UISOUNDS: + CSettings::GetInstance().SetString(CSettings::SETTING_LOOKANDFEEL_SOUNDSKIN, addonID); + break; default: return false; } diff --git a/xbmc/addons/GUIDialogAddonInfo.cpp b/xbmc/addons/GUIDialogAddonInfo.cpp index 4360324f80..a3c2cdedc9 100644 --- a/xbmc/addons/GUIDialogAddonInfo.cpp +++ b/xbmc/addons/GUIDialogAddonInfo.cpp @@ -19,8 +19,8 @@ */ #include "GUIDialogAddonInfo.h" -#include "dialogs/GUIDialogYesNo.h" -#include "dialogs/GUIDialogOK.h" + +#include "addons/AddonInstaller.h" #include "addons/AddonManager.h" #include "AddonDatabase.h" #include "FileItem.h" @@ -29,6 +29,9 @@ #include "cores/AudioEngine/DSPAddons/ActiveAEDSP.h" #include "dialogs/GUIDialogContextMenu.h" #include "dialogs/GUIDialogTextViewer.h" +#include "dialogs/GUIDialogOK.h" +#include "dialogs/GUIDialogSelect.h" +#include "dialogs/GUIDialogYesNo.h" #include "GUIUserMessages.h" #include "guilib/GUIWindowManager.h" #include "input/Key.h" @@ -38,7 +41,6 @@ #include "utils/URIUtils.h" #include "utils/log.h" #include "utils/Variant.h" -#include "addons/AddonInstaller.h" #include "Util.h" #include "interfaces/builtins/Builtins.h" @@ -111,7 +113,7 @@ bool CGUIDialogAddonInfo::OnMessage(CGUIMessage& message) } else if (iControl == CONTROL_BTN_SELECT) { - OnLaunch(); + OnSelect(); return true; } else if (iControl == CONTROL_BTN_ENABLE) @@ -173,7 +175,6 @@ void CGUIDialogAddonInfo::UpdateControls() { bool isInstalled = NULL != m_localAddon.get(); bool isEnabled = isInstalled && m_item->GetProperty("Addon.Enabled").asBoolean(); - bool isUpdatable = isInstalled && m_item->GetProperty("Addon.UpdateAvail").asBoolean(); bool isExecutable = isInstalled && (m_localAddon->Type() == ADDON_PLUGIN || m_localAddon->Type() == ADDON_SCRIPT); if (isInstalled) GrabRollbackVersions(); @@ -188,17 +189,71 @@ void CGUIDialogAddonInfo::UpdateControls() CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_ENABLE, canDisable); SET_CONTROL_LABEL(CONTROL_BTN_ENABLE, isEnabled ? 24021 : 24022); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_UPDATE, isUpdatable); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_UPDATE, isInstalled); + + CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SELECT, isEnabled && (CanOpen() || + CanRun() || (CanUse() && !m_localAddon->IsInUse()))); + SET_CONTROL_LABEL(CONTROL_BTN_SELECT, CanUse() ? 21480 : (CanOpen() ? 21478 : 21479)); + CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SETTINGS, isInstalled && m_localAddon->HasSettings()); - CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SELECT, isExecutable); CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_CHANGELOG, !isRepo); CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_ROLLBACK, m_rollbackVersions.size() > 1); } void CGUIDialogAddonInfo::OnUpdate() { - CAddonInstaller::GetInstance().InstallOrUpdate(m_addon->ID()); Close(); + + if (!m_localAddon) + return; + + CAddonDatabase database; + if (!database.Open()) + return; + + std::vector<std::pair<AddonVersion, std::string>> versions; + if (!database.GetAvailableVersions(m_localAddon->ID(), versions)) + return; + + auto* dialog = static_cast<CGUIDialogSelect*>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT)); + dialog->Reset(); + dialog->SetHeading(CVariant{21338}); + dialog->SetUseDetails(true); + + std::sort(versions.begin(), versions.end(), std::greater<std::pair<AddonVersion, std::string>>()); + + for (const auto& version : versions) + { + AddonPtr repo; + if (CAddonMgr::GetInstance().GetAddon(version.second, repo, ADDON_REPOSITORY)) + { + CFileItem item(StringUtils::Format(g_localizeStrings.Get(21339).c_str(), version.first.asString().c_str())); + item.SetProperty("Addon.Summary", repo->Name()); + item.SetIconImage(repo->Icon()); + + if (m_localAddon->Version() == version.first) + item.Select(true); + + dialog->Add(item); + } + } + + dialog->Open(); + if (dialog->IsConfirmed()) + { + auto selected = versions.at(dialog->GetSelectedLabel()); + if (!selected.second.empty()) + { + //add or remove from blacklist to toggle auto updating. if downgrading + //turn off, if upgrading to latest turn it back on + if (selected.first < m_localAddon->Version()) + database.BlacklistAddon(m_localAddon->ID()); + if (selected.first == versions.at(0).first) + database.RemoveAddonFromBlacklist(m_localAddon->ID()); + + CAddonInstaller::GetInstance().Install(m_addon->ID(), selected.first, selected.second); + } + } } void CGUIDialogAddonInfo::OnInstall() @@ -210,13 +265,38 @@ void CGUIDialogAddonInfo::OnInstall() Close(); } -void CGUIDialogAddonInfo::OnLaunch() +void CGUIDialogAddonInfo::OnSelect() { if (!m_localAddon) return; Close(); - CBuiltins::GetInstance().Execute("RunAddon(" + m_localAddon->ID() + ")"); + + if (CanOpen() || CanRun()) + CBuiltins::GetInstance().Execute("RunAddon(" + m_localAddon->ID() + ")"); + else if (CanUse()) + CAddonMgr::GetInstance().SetDefault(m_localAddon->Type(), m_localAddon->ID()); +} + +bool CGUIDialogAddonInfo::CanOpen() const +{ + return m_localAddon && m_localAddon->Type() == ADDON_PLUGIN; +} + +bool CGUIDialogAddonInfo::CanRun() const +{ + return m_localAddon && m_localAddon->Type() == ADDON_SCRIPT; +} + +bool CGUIDialogAddonInfo::CanUse() const +{ + return m_localAddon && ( + m_localAddon->Type() == ADDON_SKIN || + m_localAddon->Type() == ADDON_SCREENSAVER || + m_localAddon->Type() == ADDON_VIZ || + m_localAddon->Type() == ADDON_SCRIPT_WEATHER || + m_localAddon->Type() == ADDON_RESOURCE_LANGUAGE || + m_localAddon->Type() == ADDON_RESOURCE_UISOUNDS); } bool CGUIDialogAddonInfo::PromptIfDependency(int heading, int line2) @@ -348,6 +428,7 @@ void CGUIDialogAddonInfo::OnRollback() if ((choice=dlg->ShowAndGetChoice(buttons)) > -1) { // blacklist everything newer + //FIXME: broken. never been possible to have multiple versions in the blacklist for (unsigned int j=choice+1;j<m_rollbackVersions.size();++j) database.BlacklistAddon(m_localAddon->ID(),m_rollbackVersions[j]); std::string path = "special://home/addons/packages/"; diff --git a/xbmc/addons/GUIDialogAddonInfo.h b/xbmc/addons/GUIDialogAddonInfo.h index 53b7a276a2..f146eff081 100644 --- a/xbmc/addons/GUIDialogAddonInfo.h +++ b/xbmc/addons/GUIDialogAddonInfo.h @@ -41,7 +41,8 @@ public: // job callback void OnJobComplete(unsigned int jobID, bool success, CJob* job); -protected: + +private: void OnInitWindow(); /*! \brief Set the item to display addon info on. @@ -58,7 +59,18 @@ protected: void OnSettings(); void OnChangeLog(); void OnRollback(); - void OnLaunch(); + void OnSelect(); + + /*! Returns true if current addon can be opened (i.e is a plugin)*/ + bool CanOpen() const; + + /*! Returns true if current addon can be run (i.e is a script)*/ + bool CanRun() const; + + /*! + * Returns true if current addon is of a type that can only have one activly + * in use at a time and can be changed (e.g skins)*/ + bool CanUse() const; /*! \brief check if the add-on is a dependency of others, and if so prompt the user. \param heading the label for the heading of the prompt dialog diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h index 48f0ed5511..6cb516bc38 100644 --- a/xbmc/addons/IAddon.h +++ b/xbmc/addons/IAddon.h @@ -18,12 +18,14 @@ * <http://www.gnu.org/licenses/>. * */ -#include <memory> + +#include <stdint.h> #include <map> +#include <memory> #include <set> #include <string> -#include <stdint.h> +#include <utility> class TiXmlElement; diff --git a/xbmc/addons/Makefile b/xbmc/addons/Makefile index 7934e23bad..b0b7132f00 100644 --- a/xbmc/addons/Makefile +++ b/xbmc/addons/Makefile @@ -2,6 +2,7 @@ SRCS=Addon.cpp \ AddonCallbacks.cpp \ AddonCallbacksAddon.cpp \ AddonCallbacksAudioDSP.cpp \ + AddonCallbacksAudioEngine.cpp \ AddonCallbacksCodec.cpp \ AddonCallbacksGUI.cpp \ AddonCallbacksPVR.cpp \ diff --git a/xbmc/addons/PluginSource.cpp b/xbmc/addons/PluginSource.cpp index 091e5e9e86..ce2ced32ad 100644 --- a/xbmc/addons/PluginSource.cpp +++ b/xbmc/addons/PluginSource.cpp @@ -17,7 +17,11 @@ * <http://www.gnu.org/licenses/>. * */ + #include "PluginSource.h" + +#include <utility> + #include "AddonManager.h" #include "utils/StringUtils.h" diff --git a/xbmc/addons/Repository.cpp b/xbmc/addons/Repository.cpp index ada3364d3c..efac86ea9e 100644 --- a/xbmc/addons/Repository.cpp +++ b/xbmc/addons/Repository.cpp @@ -18,29 +18,32 @@ * */ -#include <iterator> #include "Repository.h" -#include "events/EventLog.h" -#include "events/AddonManagementEvent.h" + +#include <iterator> +#include <utility> + #include "addons/AddonDatabase.h" #include "addons/AddonInstaller.h" #include "addons/AddonManager.h" #include "addons/RepositoryUpdater.h" -#include "dialogs/GUIDialogYesNo.h" #include "dialogs/GUIDialogKaiToast.h" -#include "filesystem/File.h" +#include "dialogs/GUIDialogYesNo.h" +#include "events/AddonManagementEvent.h" +#include "events/EventLog.h" +#include "FileItem.h" #include "filesystem/Directory.h" +#include "filesystem/File.h" #include "messaging/helpers/DialogHelper.h" #include "settings/Settings.h" -#include "utils/log.h" +#include "TextureDatabase.h" +#include "URL.h" #include "utils/JobManager.h" +#include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" #include "utils/XBMCTinyXML.h" -#include "FileItem.h" -#include "TextureDatabase.h" -#include "URL.h" using namespace XFILE; using namespace ADDON; @@ -172,11 +175,12 @@ bool CRepository::Parse(const DirInfo& dir, VECADDONS &result) file = url.Get(); } + VECADDONS addons; CXBMCTinyXML doc; if (doc.LoadFile(file) && doc.RootElement() && - CAddonMgr::GetInstance().AddonsFromRepoXML(doc.RootElement(), result)) + CAddonMgr::GetInstance().AddonsFromRepoXML(doc.RootElement(), addons)) { - for (IVECADDONS i = result.begin(); i != result.end(); ++i) + for (IVECADDONS i = addons.begin(); i != addons.end(); ++i) { AddonPtr addon = *i; if (dir.zipped) @@ -195,6 +199,7 @@ bool CRepository::Parse(const DirInfo& dir, VECADDONS &result) SET_IF_NOT_EMPTY(addon->Props().changelog,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/changelog.txt")) SET_IF_NOT_EMPTY(addon->Props().fanart,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/fanart.jpg")) } + result.push_back(addon); } return true; } @@ -204,20 +209,6 @@ bool CRepository::Parse(const DirInfo& dir, VECADDONS &result) CRepositoryUpdateJob::CRepositoryUpdateJob(const RepositoryPtr& repo) : m_repo(repo) {} -void MergeAddons(std::map<std::string, AddonPtr> &addons, const VECADDONS &new_addons) -{ - for (VECADDONS::const_iterator it = new_addons.begin(); it != new_addons.end(); ++it) - { - std::map<std::string, AddonPtr>::iterator existing = addons.find((*it)->ID()); - if (existing != addons.end()) - { // already got it - replace if we have a newer version - if (existing->second->Version() < (*it)->Version()) - existing->second = *it; - } - else - addons.insert(make_pair((*it)->ID(), *it)); - } -} bool CRepositoryUpdateJob::DoWork() { @@ -226,7 +217,7 @@ bool CRepositoryUpdateJob::DoWork() database.Open(); std::string oldChecksum; - if (!database.GetRepoChecksum(m_repo->ID(), oldChecksum)) + if (database.GetRepoChecksum(m_repo->ID(), oldChecksum) == -1) oldChecksum = ""; std::string newChecksum; @@ -349,26 +340,19 @@ CRepositoryUpdateJob::FetchStatus CRepositoryUpdateJob::FetchIfChanged(const std if (oldChecksum == checksum && !oldChecksum.empty()) return STATUS_NOT_MODIFIED; - std::map<std::string, AddonPtr> uniqueAddons; for (auto it = m_repo->m_dirs.cbegin(); it != m_repo->m_dirs.cend(); ++it) { if (ShouldCancel(m_repo->m_dirs.size() + std::distance(m_repo->m_dirs.cbegin(), it), total)) return STATUS_ERROR; - VECADDONS addons; if (!CRepository::Parse(*it, addons)) { CLog::Log(LOGERROR, "CRepositoryUpdateJob[%s] failed to read or parse " "directory '%s'", m_repo->ID().c_str(), it->info.c_str()); return STATUS_ERROR; } - MergeAddons(uniqueAddons, addons); } - - for (const auto& kv : uniqueAddons) - addons.push_back(kv.second); - SetProgress(total, total); return STATUS_OK; } diff --git a/xbmc/addons/RepositoryUpdater.cpp b/xbmc/addons/RepositoryUpdater.cpp index e341ba4f52..5e9a520043 100644 --- a/xbmc/addons/RepositoryUpdater.cpp +++ b/xbmc/addons/RepositoryUpdater.cpp @@ -118,7 +118,7 @@ void CRepositoryUpdater::CheckForUpdates(const ADDON::RepositoryPtr& repo, bool m_doneEvent.Reset(); if (showProgress) SetProgressIndicator(job); - CJobManager::GetInstance().AddJob(job, this); + CJobManager::GetInstance().AddJob(job, this, CJob::PRIORITY_LOW_PAUSABLE); } else { @@ -178,10 +178,12 @@ void CRepositoryUpdater::ScheduleUpdate() if (!CAddonMgr::GetInstance().HasAddons(ADDON_REPOSITORY)) return; - auto next = std::max(CDateTime::GetCurrentDateTime(), LastUpdated() + interval); + auto prev = LastUpdated(); + auto next = std::max(CDateTime::GetCurrentDateTime(), prev + interval); int delta = std::max(1, (next - CDateTime::GetCurrentDateTime()).GetSecondsTotal() * 1000); - CLog::Log(LOGDEBUG,"CRepositoryUpdater: next update at %s", next.GetAsLocalizedDateTime().c_str()); + CLog::Log(LOGDEBUG,"CRepositoryUpdater: previous update at %s, next at %s", + prev.GetAsLocalizedDateTime().c_str(), next.GetAsLocalizedDateTime().c_str()); if (!m_timer.Start(delta)) CLog::Log(LOGERROR,"CRepositoryUpdater: failed to start timer"); diff --git a/xbmc/addons/ScreenSaver.cpp b/xbmc/addons/ScreenSaver.cpp index 3c68b7a63a..4df3a667b2 100644 --- a/xbmc/addons/ScreenSaver.cpp +++ b/xbmc/addons/ScreenSaver.cpp @@ -20,6 +20,7 @@ #include "ScreenSaver.h" #include "guilib/GraphicContext.h" #include "interfaces/generic/ScriptInvocationManager.h" +#include "settings/Settings.h" #include "utils/AlarmClock.h" #include "windowing/WindowingFactory.h" @@ -42,6 +43,11 @@ AddonPtr CScreenSaver::Clone() const return AddonPtr(new CScreenSaver(*this)); } +bool CScreenSaver::IsInUse() const +{ + return CSettings::GetInstance().GetString(CSettings::SETTING_SCREENSAVER_MODE) == ID(); +} + bool CScreenSaver::CreateScreenSaver() { if (CScriptInvocationManager::GetInstance().HasLanguageInvoker(LibPath())) diff --git a/xbmc/addons/ScreenSaver.h b/xbmc/addons/ScreenSaver.h index 1b2a7419b4..7643dfd0e9 100644 --- a/xbmc/addons/ScreenSaver.h +++ b/xbmc/addons/ScreenSaver.h @@ -35,6 +35,7 @@ public: CScreenSaver(const char *addonID); virtual ~CScreenSaver() {} virtual AddonPtr Clone() const; + virtual bool IsInUse() const; // Things that MUST be supplied by the child classes bool CreateScreenSaver(); diff --git a/xbmc/addons/Skin.h b/xbmc/addons/Skin.h index 51c1c0d967..a1278bed68 100644 --- a/xbmc/addons/Skin.h +++ b/xbmc/addons/Skin.h @@ -23,6 +23,7 @@ #include <map> #include <set> #include <vector> +#include <utility> #include "addons/Addon.h" #include "guilib/GraphicContext.h" // needed for the RESOLUTION members diff --git a/xbmc/addons/Visualisation.cpp b/xbmc/addons/Visualisation.cpp index 2a127423d7..714e3ffa6d 100644 --- a/xbmc/addons/Visualisation.cpp +++ b/xbmc/addons/Visualisation.cpp @@ -26,6 +26,7 @@ #include "guilib/WindowIDs.h" #include "music/tags/MusicInfoTag.h" #include "settings/AdvancedSettings.h" +#include "settings/Settings.h" #include "windowing/WindowingFactory.h" #include "utils/URIUtils.h" #include "utils/StringUtils.h" @@ -473,3 +474,7 @@ std::string CVisualisation::GetPresetName() return ""; } +bool CVisualisation::IsInUse() const +{ + return CSettings::GetInstance().GetString(CSettings::SETTING_MUSICPLAYER_VISUALISATION) == ID(); +} diff --git a/xbmc/addons/Visualisation.h b/xbmc/addons/Visualisation.h index ce9f069165..d250014812 100644 --- a/xbmc/addons/Visualisation.h +++ b/xbmc/addons/Visualisation.h @@ -61,6 +61,7 @@ namespace ADDON CVisualisation(const cp_extension_t *ext) : CAddonDll<DllVisualisation, Visualisation, VIS_PROPS>(ext) {} virtual void OnInitialize(int iChannels, int iSamplesPerSec, int iBitsPerSample); virtual void OnAudioData(const float* pAudioData, int iAudioDataLength); + virtual bool IsInUse() const; bool Create(int x, int y, int w, int h, void *device); void Start(int iChannels, int iSamplesPerSec, int iBitsPerSample, const std::string &strSongName); void AudioData(const float *pAudioData, int iAudioDataLength, float *pFreqData, int iFreqDataLength); diff --git a/xbmc/addons/addon-bindings.mk b/xbmc/addons/addon-bindings.mk index e94975bfec..8b67d40cf3 100644 --- a/xbmc/addons/addon-bindings.mk +++ b/xbmc/addons/addon-bindings.mk @@ -3,6 +3,7 @@ BINDINGS+=xbmc/addons/include/xbmc_addon_dll.h BINDINGS+=xbmc/addons/include/xbmc_addon_types.h BINDINGS+=xbmc/addons/include/kodi_adsp_dll.h BINDINGS+=xbmc/addons/include/kodi_adsp_types.h +BINDINGS+=xbmc/addons/include/kodi_audioengine_types.h BINDINGS+=xbmc/addons/include/xbmc_audioenc_dll.h BINDINGS+=xbmc/addons/include/xbmc_audioenc_types.h BINDINGS+=xbmc/addons/include/kodi_audiodec_dll.h @@ -18,6 +19,7 @@ BINDINGS+=xbmc/addons/include/xbmc_vis_types.h BINDINGS+=xbmc/addons/include/xbmc_stream_utils.hpp BINDINGS+=addons/library.xbmc.addon/libXBMC_addon.h BINDINGS+=addons/library.kodi.adsp/libKODI_adsp.h +BINDINGS+=addons/library.kodi.audioengine/libKODI_audioengine.h BINDINGS+=addons/library.kodi.guilib/libKODI_guilib.h BINDINGS+=addons/library.xbmc.pvr/libXBMC_pvr.h BINDINGS+=addons/library.xbmc.codec/libXBMC_codec.h diff --git a/xbmc/addons/include/kodi_audioengine_types.h b/xbmc/addons/include/kodi_audioengine_types.h new file mode 100644 index 0000000000..e745924ca3 --- /dev/null +++ b/xbmc/addons/include/kodi_audioengine_types.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2005-2015 Team KODI + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +/*! + * Common data structures shared between KODI and KODI's binary add-ons + */ + +#ifndef __AUDIOENGINE_TYPES_H__ +#define __AUDIOENGINE_TYPES_H__ + +#ifdef TARGET_WINDOWS +#include <windows.h> +#else +#ifndef __cdecl +#define __cdecl +#endif +#ifndef __declspec +#define __declspec(X) +#endif +#endif + +#include <cstddef> + +#undef ATTRIBUTE_PACKED +#undef PRAGMA_PACK_BEGIN +#undef PRAGMA_PACK_END + +#if defined(__GNUC__) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ATTRIBUTE_PACKED __attribute__ ((packed)) +#define PRAGMA_PACK 0 +#endif +#endif + +#if !defined(ATTRIBUTE_PACKED) +#define ATTRIBUTE_PACKED +#define PRAGMA_PACK 1 +#endif + +/* current Audio DSP API version */ +#define KODI_AUDIOENGINE_API_VERSION "0.0.1" + +/* min. Audio DSP API version */ +#define KODI_AUDIOENGINE_MIN_API_VERSION "0.0.1" + + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * A stream handle pointer, which is only used internally by the addon stream handle + */ + typedef void AEStreamHandle; + + /** + * The audio format structure that fully defines a stream's audio information + */ + typedef struct AudioEngineFormat + { + /** + * The stream's data format (eg, AE_FMT_S16LE) + */ + enum AEDataFormat m_dataFormat; + + /** + * The stream's sample rate (eg, 48000) + */ + unsigned int m_sampleRate; + + /** + * The encoded streams sample rate if a bitstream, otherwise undefined + */ + unsigned int m_encodedRate; + + /** + * The amount of used speaker channels + */ + unsigned int m_channelCount; + + /** + * The stream's channel layout + */ + enum AEChannel m_channels[AE_CH_MAX]; + + /** + * The number of frames per period + */ + unsigned int m_frames; + + /** + * The number of samples in one frame + */ + unsigned int m_frameSamples; + + /** + * The size of one frame in bytes + */ + unsigned int m_frameSize; + + AudioEngineFormat() + { + m_dataFormat = AE_FMT_INVALID; + m_sampleRate = 0; + m_encodedRate = 0; + m_frames = 0; + m_frameSamples = 0; + m_frameSize = 0; + m_channelCount = 0; + + for (unsigned int ch = 0; ch < AE_CH_MAX; ch++) + { + m_channels[ch] = AE_CH_NULL; + } + } + + bool compareFormat(const AudioEngineFormat *fmt) + { + if (!fmt) + { + return false; + } + + if (m_dataFormat != fmt->m_dataFormat || + m_sampleRate != fmt->m_sampleRate || + m_encodedRate != fmt->m_encodedRate || + m_frames != fmt->m_frames || + m_frameSamples != fmt->m_frameSamples || + m_frameSize != fmt->m_frameSize || + m_channelCount != fmt->m_channelCount) + { + return false; + } + + for (unsigned int ch = 0; ch < AE_CH_MAX; ch++) + { + if (fmt->m_channels[ch] != m_channels[ch]) + { + return false; + } + } + + return true; + } + } AudioEngineFormat; + +#ifdef __cplusplus +} +#endif + +#endif //__AUDIOENGINE_TYPES_H__ diff --git a/xbmc/addons/include/xbmc_epg_types.h b/xbmc/addons/include/xbmc_epg_types.h index efd7d13428..5ca14295c5 100644 --- a/xbmc/addons/include/xbmc_epg_types.h +++ b/xbmc/addons/include/xbmc_epg_types.h @@ -61,6 +61,10 @@ /* Set EPGTAG.iGenreType to EPG_GENRE_USE_STRING to transfer genre strings to XBMC */ #define EPG_GENRE_USE_STRING 0x100 +/* EPG_TAG.iFlags values */ +const unsigned int EPG_TAG_FLAG_UNDEFINED = 0x00000000; /*!< @brief nothing special to say about this entry */ +const unsigned int EPG_TAG_FLAG_IS_SERIES = 0x00000001; /*!< @brief this EPG entry is part of a series */ + #ifdef __cplusplus extern "C" { #endif @@ -94,6 +98,7 @@ extern "C" { int iEpisodeNumber; /*!< @brief (optional) episode number */ int iEpisodePartNumber; /*!< @brief (optional) episode part number */ const char * strEpisodeName; /*!< @brief (optional) episode name */ + unsigned int iFlags; /*!< @brief (optional) bit field of independent flags associated with the EPG entry */ } ATTRIBUTE_PACKED EPG_TAG; #ifdef __cplusplus diff --git a/xbmc/addons/include/xbmc_pvr_types.h b/xbmc/addons/include/xbmc_pvr_types.h index b3b36b4e97..c5ab20b5b9 100644 --- a/xbmc/addons/include/xbmc_pvr_types.h +++ b/xbmc/addons/include/xbmc_pvr_types.h @@ -79,10 +79,10 @@ struct DemuxPacket; #define PVR_STREAM_MAX_STREAMS 20 /* current PVR API version */ -#define XBMC_PVR_API_VERSION "4.0.0" +#define XBMC_PVR_API_VERSION "4.1.0" /* min. PVR API version */ -#define XBMC_PVR_MIN_API_VERSION "4.0.0" +#define XBMC_PVR_MIN_API_VERSION "4.1.0" #ifdef __cplusplus extern "C" { @@ -142,6 +142,7 @@ extern "C" { const unsigned int PVR_TIMER_TYPE_SUPPORTS_MAX_RECORDINGS = 0x00100000; /*!< @brief this type supports specifying a maximum recordings setting' (PVR_TIMER.iMaxRecordings) */ const unsigned int PVR_TIMER_TYPE_REQUIRES_EPG_TAG_ON_CREATE = 0x00200000; /*!< @brief this type shold not appear on any create menus which don't provide an associated EPG tag */ const unsigned int PVR_TIMER_TYPE_FORBIDS_EPG_TAG_ON_CREATE = 0x00400000; /*!< @brief this type should not appear on any create menus which provide an associated EPG tag */ + const unsigned int PVR_TIMER_TYPE_REQUIRES_EPG_SERIES_ON_CREATE = 0x00800000; /*!< @brief this type should not appear on any create menus unless associated with an EPG tag with 'series' attributes (EPG_TAG.iFlags & EPG_TAG_FLAG_IS_SERIES || EPG_TAG.iSeriesNumber > 0 || EPG_TAG.iEpisodeNumber > 0 || EPG_TAG.iEpisodePartNumber > 0). Implies PVR_TIMER_TYPE_REQUIRES_EPG_TAG_ON_CREATE */ /*! * @brief PVR timer weekdays (PVR_TIMER.iWeekdays values) diff --git a/xbmc/cores/AudioEngine/AEFactory.h b/xbmc/cores/AudioEngine/AEFactory.h index 04a41a1afe..ba303fd515 100644 --- a/xbmc/cores/AudioEngine/AEFactory.h +++ b/xbmc/cores/AudioEngine/AEFactory.h @@ -19,6 +19,7 @@ * */ +#include <utility> #include <vector> #include "Interfaces/AE.h" diff --git a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSP.cpp b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSP.cpp index 5ce2a5c820..37c4c7d500 100644 --- a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSP.cpp +++ b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSP.cpp @@ -19,35 +19,37 @@ */ #include "ActiveAEDSP.h" -#include "ActiveAEDSPProcess.h" + +#include <utility> extern "C" { #include "libavutil/channel_layout.h" } +#include "ActiveAEDSPProcess.h" +#include "addons/AddonInstaller.h" +#include "addons/GUIDialogAddonSettings.h" +#include "Application.h" #include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" #include "cores/AudioEngine/Interfaces/AEResample.h" -#include "cores/IPlayer.h" #include "cores/AudioEngine/Utils/AEUtil.h" - -#include "Application.h" -#include "guiinfo/GUIInfoLabels.h" -#include "GUIUserMessages.h" -#include "addons/AddonInstaller.h" -#include "addons/GUIDialogAddonSettings.h" +#include "cores/IPlayer.h" +#include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogOK.h" #include "dialogs/GUIDialogSelect.h" -#include "dialogs/GUIDialogKaiToast.h" +#include "guiinfo/GUIInfoLabels.h" #include "guilib/GUIWindowManager.h" +#include "GUIUserMessages.h" #include "messaging/ApplicationMessenger.h" #include "messaging/helpers/DialogHelper.h" #include "settings/AdvancedSettings.h" +#include "settings/dialogs/GUIDialogAudioDSPManager.h" #include "settings/MediaSettings.h" #include "settings/MediaSourceSettings.h" #include "settings/Settings.h" -#include "settings/dialogs/GUIDialogAudioDSPManager.h" -#include "utils/StringUtils.h" #include "utils/JobManager.h" +#include "utils/StringUtils.h" + using namespace ADDON; using namespace ActiveAE; diff --git a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPDatabase.cpp b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPDatabase.cpp index 587e884553..322d2509c3 100644 --- a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPDatabase.cpp +++ b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPDatabase.cpp @@ -212,7 +212,7 @@ bool CActiveAEDSPDatabase::AddUpdateMode(CActiveAEDSPMode &mode) if (NULL == m_pDS.get()) return false; std::string strSQL = PrepareSQL("SELECT * FROM modes WHERE modes.iAddonId=%i AND modes.iAddonModeNumber=%i AND modes.iType=%i", mode.AddonID(), mode.AddonModeNumber(), mode.ModeType()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() > 0) { /* get user selected settings */ @@ -245,7 +245,7 @@ bool CActiveAEDSPDatabase::AddUpdateMode(CActiveAEDSPMode &mode) mode.AddonModeName().c_str(), (mode.HasSettingsDialog() ? 1 : 0), mode.AddonID(), mode.AddonModeNumber(), mode.ModeType()); - bReturn = m_pDS->exec(strSQL.c_str()); + bReturn = m_pDS->exec(strSQL); } else { // add the items @@ -283,7 +283,7 @@ bool CActiveAEDSPDatabase::AddUpdateMode(CActiveAEDSPMode &mode) mode.AddonID(), mode.AddonModeNumber(), (mode.HasSettingsDialog() ? 1 : 0)); - bReturn = m_pDS->exec(strSQL.c_str()); + bReturn = m_pDS->exec(strSQL); } } catch (...) @@ -307,7 +307,7 @@ int CActiveAEDSPDatabase::GetModes(AE_DSP_MODELIST &results, int modeType) std::string strQuery=PrepareSQL("SELECT * FROM modes WHERE modes.iType=%i ORDER BY iPosition", modeType); - m_pDS->query( strQuery.c_str() ); + m_pDS->query( strQuery ); if (m_pDS->num_rows() > 0) { try @@ -384,7 +384,7 @@ bool CActiveAEDSPDatabase::GetActiveDSPSettings(const CFileItem &item, CAudioSet URIUtils::Split(item.GetPath(), strPath, strFileName); std::string strSQL=PrepareSQL("SELECT * FROM settings WHERE settings.strPath='%s' and settings.strFileName='%s'", strPath.c_str() , strFileName.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() > 0) { // get the audio dsp settings info settings.m_MasterStreamTypeSel = m_pDS->fv("MasterStreamTypeSel").get_asInt(); @@ -418,7 +418,7 @@ void CActiveAEDSPDatabase::SetActiveDSPSettings(const CFileItem &item, const CAu std::string strPath, strFileName; URIUtils::Split(item.GetPath(), strPath, strFileName); std::string strSQL = StringUtils::Format("select * from settings WHERE settings.strPath='%s' and settings.strFileName='%s'", strPath.c_str() , strFileName.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() > 0) { m_pDS->close(); @@ -436,7 +436,7 @@ void CActiveAEDSPDatabase::SetActiveDSPSettings(const CFileItem &item, const CAu setting.m_MasterModes[setting.m_MasterStreamType][setting.m_MasterStreamBase], strPath.c_str(), strFileName.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return ; } else @@ -458,7 +458,7 @@ void CActiveAEDSPDatabase::SetActiveDSPSettings(const CFileItem &item, const CAu setting.m_MasterStreamType, setting.m_MasterStreamBase, setting.m_MasterModes[setting.m_MasterStreamType][setting.m_MasterStreamBase]); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } } catch (...) diff --git a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPMode.h b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPMode.h index ed6344b53e..a6ded932af 100644 --- a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPMode.h +++ b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPMode.h @@ -19,6 +19,8 @@ * */ +#include <utility> + #include "ActiveAEDSPAddon.h" #include "threads/CriticalSection.h" #include "utils/Observer.h" diff --git a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPProcess.cpp b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPProcess.cpp index fb6a8844c2..47806c209e 100644 --- a/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPProcess.cpp +++ b/xbmc/cores/AudioEngine/DSPAddons/ActiveAEDSPProcess.cpp @@ -18,23 +18,24 @@ * */ -#include "Application.h" -#include "settings/MediaSettings.h" - -#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" -#include "cores/AudioEngine/AEResampleFactory.h" -#include "cores/AudioEngine/Utils/AEUtil.h" -#include "cores/IPlayer.h" -#include "utils/TimeUtils.h" - #include "ActiveAEDSPProcess.h" -#include "ActiveAEDSPMode.h" + +#include <utility> extern "C" { #include "libavutil/channel_layout.h" #include "libavutil/opt.h" } +#include "ActiveAEDSPMode.h" +#include "Application.h" +#include "cores/AudioEngine/AEResampleFactory.h" +#include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" +#include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/IPlayer.h" +#include "settings/MediaSettings.h" +#include "utils/TimeUtils.h" + using namespace ADDON; using namespace ActiveAE; diff --git a/xbmc/cores/AudioEngine/Interfaces/AE.h b/xbmc/cores/AudioEngine/Interfaces/AE.h index 7ec305351e..190d351865 100644 --- a/xbmc/cores/AudioEngine/Interfaces/AE.h +++ b/xbmc/cores/AudioEngine/Interfaces/AE.h @@ -19,9 +19,10 @@ * */ -#include <list> #include <map> +#include <list> #include <vector> +#include <utility> #include "system.h" @@ -257,10 +258,11 @@ public: virtual bool HasDSP() { return false; }; /** - * Gets the currently used sink format. + * Get the current sink data format * - * @return The current sink format. + * @param Current sink data format. For more details see AEAudioFormat. + * @return Returns true on success, else false. */ - virtual AEAudioFormat GetCurrentSinkFormat() = 0; + virtual bool GetCurrentSinkFormat(AEAudioFormat &SinkFormat) { return false; } }; diff --git a/xbmc/cores/AudioEngine/Interfaces/AEStream.h b/xbmc/cores/AudioEngine/Interfaces/AEStream.h index a7f8fd67cf..2c33afd481 100644 --- a/xbmc/cores/AudioEngine/Interfaces/AEStream.h +++ b/xbmc/cores/AudioEngine/Interfaces/AEStream.h @@ -20,6 +20,7 @@ */ #include "cores/AudioEngine/Utils/AEAudioFormat.h" +#include "cores/AudioEngine/Utils/AEStreamData.h" #include "cores/IAudioCallback.h" #include <stdint.h> @@ -28,17 +29,6 @@ extern "C" { } /** - * Bit options to pass to IAE::GetStream - */ -enum AEStreamOptions -{ - AESTREAM_FORCE_RESAMPLE = 0x01, /* force resample even if rates match */ - AESTREAM_PAUSED = 0x02, /* create the stream paused */ - AESTREAM_AUTOSTART = 0x04, /* autostart the stream when enough data is buffered */ - AESTREAM_BYPASS_ADSP = 0x08 /* if this option is set the ADSP-System is bypassed and raw stream will be passed through IAESink */ -}; - -/** * IAEStream Stream Interface for streaming audio */ class IAEStream diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp index 0d80d1e243..ca295496bf 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp @@ -22,6 +22,7 @@ #include "AESinkPULSE.h" #include "utils/log.h" #include "Util.h" +#include "utils/TimeUtils.h" #include "guilib/LocalizeStrings.h" #include "Application.h" @@ -439,6 +440,8 @@ CAESinkPULSE::CAESinkPULSE() m_MainLoop = NULL; m_BytesPerSecond = 0; m_BufferSize = 0; + m_filled_bytes = 0; + m_lastPackageStamp = 0; m_Channels = 0; m_Stream = NULL; m_Context = NULL; @@ -462,6 +465,8 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device) m_passthrough = false; m_BytesPerSecond = 0; m_BufferSize = 0; + m_filled_bytes = 0; + m_lastPackageStamp = 0; m_Channels = 0; m_Stream = NULL; m_Context = NULL; @@ -694,6 +699,8 @@ void CAESinkPULSE::Deinitialize() m_IsAllocated = false; m_passthrough = false; m_periodSize = 0; + m_filled_bytes = 0; + m_lastPackageStamp = 0; if (m_Stream) Drain(); @@ -730,25 +737,24 @@ void CAESinkPULSE::GetDelay(AEDelayStatus& status) status.SetDelay(0); return; } - int error = 0; - pa_usec_t latency = (pa_usec_t) -1; + pa_threaded_mainloop_lock(m_MainLoop); - if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0) - { - if (error == -PA_ERR_NODATA) - { - WaitForOperation(pa_stream_update_timing_info(m_Stream, NULL,NULL), m_MainLoop, "Update Timing Information"); - if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0) - { - CLog::Log(LOGDEBUG, "GetDelay - Failed to get Latency %d", error); - } - } - } - if (error < 0 ) - latency = (pa_usec_t) 0; + const pa_timing_info* pti = pa_stream_get_timing_info(m_Stream); + // only incorporate local sink delay + internal PA transport delay + double sink_delay = (pti->configured_sink_usec / 1000000.0); + double transport_delay = pti->transport_usec / 1000000.0; + + uint64_t diff = CurrentHostCounter() - m_lastPackageStamp; + unsigned int bytes_played = (unsigned int) ((double) diff * (double) m_BytesPerSecond / (double) CurrentHostFrequency() + 0.5); + + int buffer_delay = m_filled_bytes - bytes_played; + if (buffer_delay < 0) + buffer_delay = 0; pa_threaded_mainloop_unlock(m_MainLoop); - status.SetDelay(latency / 1000000.0); + + double delay = buffer_delay / (double) m_BytesPerSecond + sink_delay + transport_delay; + status.SetDelay(delay); } double CAESinkPULSE::GetCacheTotal() @@ -775,6 +781,7 @@ unsigned int CAESinkPULSE::AddPackets(uint8_t **data, unsigned int frames, unsig while ((length = pa_stream_writable_size(m_Stream)) < m_periodSize) pa_threaded_mainloop_wait(m_MainLoop); + unsigned int free = length; length = std::min((unsigned int)length, available); int error = pa_stream_write(m_Stream, buffer, length, NULL, 0, PA_SEEK_RELATIVE); @@ -785,6 +792,8 @@ unsigned int CAESinkPULSE::AddPackets(uint8_t **data, unsigned int frames, unsig CLog::Log(LOGERROR, "CPulseAudioDirectSound::AddPackets - pa_stream_write failed\n"); return 0; } + m_lastPackageStamp = CurrentHostCounter(); + m_filled_bytes = m_BufferSize - (free - length); unsigned int res = (unsigned int)(length / m_format.m_frameSize); return res; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h index 46e9db50cb..c04bc18291 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h @@ -71,6 +71,8 @@ private: pa_cvolume m_Volume; bool m_volume_needs_update; uint32_t m_periodSize; + uint64_t m_lastPackageStamp; + uint64_t m_filled_bytes; pa_context *m_Context; pa_threaded_mainloop *m_MainLoop; diff --git a/xbmc/cores/AudioEngine/Utils/AEChannelInfo.h b/xbmc/cores/AudioEngine/Utils/AEChannelInfo.h index 199ead5e33..d101c17880 100644 --- a/xbmc/cores/AudioEngine/Utils/AEChannelInfo.h +++ b/xbmc/cores/AudioEngine/Utils/AEChannelInfo.h @@ -25,7 +25,11 @@ #include "AEChannelData.h" +class CHelper_libKODI_audioengine; + class CAEChannelInfo { + friend class CHelper_libKODI_audioengine; + public: CAEChannelInfo(); CAEChannelInfo(const enum AEChannel* rhs); diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamData.h b/xbmc/cores/AudioEngine/Utils/AEStreamData.h new file mode 100644 index 0000000000..ce6e6e32d2 --- /dev/null +++ b/xbmc/cores/AudioEngine/Utils/AEStreamData.h @@ -0,0 +1,31 @@ +#pragma once +/* + * Copyright (C) 2010-2015 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +/** + * Bit options to pass to IAE::MakeStream + */ +enum AEStreamOptions +{ + AESTREAM_FORCE_RESAMPLE = 1 << 0, /* force resample even if rates match */ + AESTREAM_PAUSED = 1 << 1, /* create the stream paused */ + AESTREAM_AUTOSTART = 1 << 2, /* autostart the stream when enough data is buffered */ + AESTREAM_BYPASS_ADSP = 1 << 3 /* if this option is set the ADSP-System is bypassed and the raw stream will be passed through IAESink */ +}; diff --git a/xbmc/cores/DllLoader/Win32DllLoader.h b/xbmc/cores/DllLoader/Win32DllLoader.h index 0839555fcc..9661eebc6b 100644 --- a/xbmc/cores/DllLoader/Win32DllLoader.h +++ b/xbmc/cores/DllLoader/Win32DllLoader.h @@ -22,6 +22,8 @@ * */ +#include <vector> + #include "LibraryLoader.h" class Win32DllLoader : public LibraryLoader diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp index d0775e205d..367ae2c3a9 100644 --- a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp +++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp @@ -1751,7 +1751,7 @@ extern "C" } else if (!IS_STD_STREAM(stream)) { - return clearerr(stream); + clearerr(stream); } } diff --git a/xbmc/cores/DllLoader/exports/wrapper.c b/xbmc/cores/DllLoader/exports/wrapper.c index a9225e5c9c..e3636623ef 100644 --- a/xbmc/cores/DllLoader/exports/wrapper.c +++ b/xbmc/cores/DllLoader/exports/wrapper.c @@ -197,7 +197,7 @@ int __wrap_ferror(FILE *stream) void __wrap_clearerr(FILE *stream) { - return dll_clearerr(stream); + dll_clearerr(stream); } int __wrap_feof(FILE *stream) diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 46c5337b4a..987714f134 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -20,6 +20,7 @@ #include "system.h" +#include <cstdlib> // std::abs(int) prototype #include <algorithm> #include "BaseRenderer.h" #include "settings/DisplaySettings.h" @@ -222,11 +223,20 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RESOLUTION current, float& weight) { RESOLUTION_INFO curr = g_graphicsContext.GetResInfo(current); + RESOLUTION orig_res = CDisplaySettings::GetInstance().GetCurrentResolution(); + + if (orig_res <= RES_DESKTOP) + orig_res = RES_DESKTOP; + + RESOLUTION_INFO orig = g_graphicsContext.GetResInfo(orig_res); float fRefreshRate = fps; float last_diff = fRefreshRate; + int curr_diff = std::abs((int) m_sourceWidth - curr.iScreenWidth); + int loop_diff = 0; + // Find closest refresh rate for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) { @@ -239,7 +249,25 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES || info.iScreen != curr.iScreen || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK) || info.fRefreshRate < (fRefreshRate * multiplier / 1.001) - 0.001) - continue; + { + // evaluate all higher modes and evalute them + // concerning dimension and refreshrate weight + // skip lower resolutions + if (((int) m_sourceWidth < orig.iScreenWidth) // orig res large enough + || (info.iScreenWidth < orig.iScreenWidth) // new width would be smaller + || (info.iScreenHeight < orig.iScreenHeight) // new height would be smaller + || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) // don't switch to interlaced modes + { + continue; + } + } + + // Allow switching to larger resolution: + // e.g. if m_sourceWidth == 3840 and we have a 3840 mode - use this one + // if it has a matching fps mode, which is evaluated below + + loop_diff = std::abs((int) m_sourceWidth - info.iScreenWidth); + curr_diff = std::abs((int) m_sourceWidth - curr.iScreenWidth); // For 3D choose the closest refresh rate if(CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) @@ -260,6 +288,9 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES int c_weight = MathUtils::round_int(RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier) * 1000.0); int i_weight = MathUtils::round_int(RefreshWeight(info.fRefreshRate, fRefreshRate * multiplier) * 1000.0); + RESOLUTION current_bak = current; + RESOLUTION_INFO curr_bak = curr; + // Closer the better, prefer higher refresh rate if the same if ((i_weight < c_weight) || (i_weight == c_weight && info.fRefreshRate > curr.fRefreshRate)) @@ -267,6 +298,21 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES current = (RESOLUTION)i; curr = info; } + // use case 1080p50 vs 3840x2160@25 for 3840@25 content + // prefer the higher resolution of 3840 + if (i_weight == c_weight && (loop_diff < curr_diff)) + { + current = (RESOLUTION)i; + curr = info; + } + // same as above but iterating with 3840@25 set and overwritten + // by e.g. 1080@50 - restore backup in that case + // to give priority to the better matching width + if (i_weight == c_weight && (loop_diff > curr_diff)) + { + current = current_bak; + curr = curr_bak; + } } } diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h index e5be98b695..d6a7140f54 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.h +++ b/xbmc/cores/VideoRenderers/BaseRenderer.h @@ -20,13 +20,14 @@ * */ +#include <utility> #include <vector> #include "guilib/Resolution.h" #include "guilib/Geometry.h" #include "RenderFormats.h" #include "RenderFeatures.h" - +
#define MAX_PLANES 3 #define MAX_FIELDS 3 #define NUM_BUFFERS 6 diff --git a/xbmc/cores/VideoRenderers/DXVAHD.cpp b/xbmc/cores/VideoRenderers/DXVAHD.cpp index fb21b70f2f..fa5559b7e8 100644 --- a/xbmc/cores/VideoRenderers/DXVAHD.cpp +++ b/xbmc/cores/VideoRenderers/DXVAHD.cpp @@ -32,14 +32,12 @@ #include "RenderFlags.h" #include "settings/AdvancedSettings.h" #include "settings/MediaSettings.h" -#include "utils/AutoPtrHandle.h" #include "utils/Log.h" #include "utils/win32/memcpy_sse2.h" #include "win32/WIN32Util.h" #include "windowing/WindowingFactory.h" using namespace DXVA; -using namespace AUTOPTR; #define LOGIFERROR(a) \ do { \ @@ -343,8 +341,8 @@ bool CProcessorHD::OpenProcessor() cs.Usage = 0; // 0 - Playback, 1 - Processing cs.RGB_Range = 0; // 0 - Full (0-255), 1 - Limited (16-235) cs.YCbCr_Matrix = m_flags & CONF_FLAGS_YUVCOEF_BT709 ? 1 : 0; // 0 - BT.601, 1 - BT.709 - cs.YCbCr_xvYCC = m_flags & CONF_FLAGS_YUV_FULLRANGE ? 1 : 0; // 0 - Conventional YCbCr, 1 - xvYCC - cs.Nominal_Range = 0; // 2 - Full luminance range [0-255], 1 - Studio luminance range [16-235], 0 - driver defaults + cs.YCbCr_xvYCC = 1; // 0 - Conventional YCbCr, 1 - xvYCC + cs.Nominal_Range = m_flags & CONF_FLAGS_YUV_FULLRANGE ? 2 : 1; // 2 - Full luminance range [0-255], 1 - Studio luminance range [16-235], 0 - driver defaults m_pVideoContext->VideoProcessorSetStreamColorSpace(m_pVideoProcessor, DEFAULT_STREAM_INDEX, &cs); // Output background color (black) @@ -700,10 +698,10 @@ bool CProcessorHD::Render(CRect src, CRect dst, ID3D11Resource* target, ID3D11Vi // Output color space D3D11_VIDEO_PROCESSOR_COLOR_SPACE colorSpace = {}; colorSpace.Usage = 0; // 0 - playback, 1 - video processing - colorSpace.RGB_Range = g_Windowing.UseLimitedColor() ? 1 : 0; // 0 - 0-255, 1 - 16-235 + colorSpace.RGB_Range = 0; // 0 - 0-255, 1 - 16-235 colorSpace.YCbCr_Matrix = 1; // 0 - BT.601, 1 = BT.709 colorSpace.YCbCr_xvYCC = 1; // 0 - Conventional YCbCr, 1 - xvYCC - colorSpace.Nominal_Range = 0; // 2 - 0-255, 1 = 16-235, 0 - undefined + colorSpace.Nominal_Range = g_Windowing.UseLimitedColor() ? 1 : 2; // 2 - 0-255, 1 = 16-235, 0 - undefined m_pVideoContext->VideoProcessorSetOutputColorSpace(m_pVideoProcessor, &colorSpace); diff --git a/xbmc/cores/VideoRenderers/OverlayRendererGUI.cpp b/xbmc/cores/VideoRenderers/OverlayRendererGUI.cpp index 7ca0f3b40b..5c11cca40f 100644 --- a/xbmc/cores/VideoRenderers/OverlayRendererGUI.cpp +++ b/xbmc/cores/VideoRenderers/OverlayRendererGUI.cpp @@ -125,11 +125,17 @@ COverlayText::COverlayText(CDVDOverlayText * src) } else { - m_align = ALIGN_VIDEO; + if(m_subalign == SUBTITLE_ALIGN_TOP_INSIDE || + m_subalign == SUBTITLE_ALIGN_BOTTOM_INSIDE) + m_align = ALIGN_VIDEO; + else + m_align = ALIGN_SCREEN; + m_pos = POSITION_RELATIVE; m_x = 0.5f; - if(m_subalign == SUBTITLE_ALIGN_TOP_INSIDE - || m_subalign == SUBTITLE_ALIGN_TOP_OUTSIDE) + + if(m_subalign == SUBTITLE_ALIGN_TOP_INSIDE || + m_subalign == SUBTITLE_ALIGN_TOP_OUTSIDE) m_y = 0.0f; else m_y = 1.0f; diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index f35e0b3bbd..24edf5a92e 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -1224,11 +1224,12 @@ void CXBMCRenderManager::DiscardBuffer() m_presentevent.notifyAll(); } -bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &bufferLevel) +bool CXBMCRenderManager::GetStats(double &sleeptime, double &pts, int &queued, int &discard) { CSingleLock lock(m_presentlock); sleeptime = m_sleeptime; pts = m_presentpts; - bufferLevel = m_queued.size() + m_discard.size(); + queued = m_queued.size(); + discard = m_discard.size(); return true; } diff --git a/xbmc/cores/VideoRenderers/RenderManager.h b/xbmc/cores/VideoRenderers/RenderManager.h index f43bff1254..8843217e78 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.h +++ b/xbmc/cores/VideoRenderers/RenderManager.h @@ -186,7 +186,7 @@ public: * Can be called by player for lateness detection. This is done best by * looking at the end of the queue. */ - bool GetStats(double &sleeptime, double &pts, int &bufferLevel); + bool GetStats(double &sleeptime, double &pts, int &queued, int &discard); /** * Video player call this on flush in oder to discard any queued frames diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp index 98c1a1c16f..1dea24febb 100644 --- a/xbmc/cores/VideoRenderers/WinRenderer.cpp +++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp @@ -1170,7 +1170,7 @@ CRenderInfo CWinRenderer::GetRenderInfo() CRenderInfo info; info.formats = m_formats; info.max_buffer_size = NUM_BUFFERS; - if (m_format == RENDER_FMT_DXVA && m_processor) + if (m_renderMethod == RENDER_DXVA && m_processor) info.optimal_buffer_size = m_processor->Size(); else info.optimal_buffer_size = 3; @@ -1186,7 +1186,7 @@ void CWinRenderer::ReleaseBuffer(int idx) bool CWinRenderer::NeedBufferForRef(int idx) { // check if processor wants to keep past frames - if (m_format == RENDER_FMT_DXVA && m_processor) + if (m_renderMethod == RENDER_DXVA && m_processor) { DXVABuffer** buffers = (DXVABuffer**)m_VideoBuffers; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp index a65af666a9..e00f5363fb 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDCodecUtils.cpp @@ -270,7 +270,7 @@ DVDVideoPicture* CDVDCodecUtils::ConvertToYUV422PackedPicture(DVDVideoPicture *p struct SwsContext *ctx = sws_getContext(pSrc->iWidth, pSrc->iHeight, PIX_FMT_YUV420P, pPicture->iWidth, pPicture->iHeight, (AVPixelFormat)dstformat, - SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); + SWS_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL); sws_scale(ctx, src, srcStride, 0, pSrc->iHeight, dst, dstStride); sws_freeContext(ctx); } diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp index 06f81c895c..dca4bdf0d1 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp @@ -243,14 +243,17 @@ CDVDOverlay* CDVDOverlayCodecFFmpeg::GetOverlay() m_height = m_pCodecContext->height; m_width = m_pCodecContext->width; - // ETSI EN 300 743 V1.3.1 - // 5.3.1 - // Absence of a DDS in a stream implies that the stream is coded in accordance with EN 300 743 (V1.2.1) [5] and that a - // display width of 720 pixels and a display height of 576 lines may be assumed. - if (!m_height && !m_width) + if (m_pCodecContext->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { - m_width = 720; - m_height = 576; + // ETSI EN 300 743 V1.3.1 + // 5.3.1 + // Absence of a DDS in a stream implies that the stream is coded in accordance with EN 300 743 (V1.2.1) [5] and that a + // display width of 720 pixels and a display height of 576 lines may be assumed. + if (!m_height && !m_width) + { + m_width = 720; + m_height = 576; + } } RENDER_STEREO_MODE render_stereo_mode = g_graphicsContext.GetStereoMode(); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp index a7b7369cee..858e0754c2 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp @@ -33,6 +33,7 @@ extern "C" { #include "cores/dvdplayer/DVDCodecs/DVDCodecUtils.h" #include "cores/FFmpeg.h" #include "osx/CocoaInterface.h" +#include "osx/DarwinUtils.h" #include "windowing/WindowingFactory.h" #include "utils/BitstreamConverter.h" #include "utils/log.h" @@ -355,6 +356,8 @@ bool CDVDVideoCodecVDA::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) } CFRelease(decoderConfiguration); CFRelease(destinationImageBufferAttributes); + if (CDarwinUtils::DeviceHasLeakyVDA()) + CFRelease(pixelFormat); if (status != kVDADecoderNoErr) { if (status == kVDADecoderDecoderFailedErr) @@ -388,6 +391,11 @@ void CDVDVideoCodecVDA::Dispose() free(m_videobuffer.data[2]), m_videobuffer.data[2] = NULL; m_videobuffer.iFlags = 0; } + else + { + while (m_queue_depth) + DisplayQueuePop(); + } if (m_bitstream) delete m_bitstream, m_bitstream = NULL; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp index e350e69b9f..85bca2ae7b 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp @@ -33,13 +33,11 @@ #include "../DVDCodecUtils.h" #include "DXVA.h" #include "settings/AdvancedSettings.h" -#include "utils/AutoPtrHandle.h" #include "utils/Log.h" #include "utils/StringUtils.h" #include "windowing/WindowingFactory.h" using namespace DXVA; -using namespace AUTOPTR; static void RelBufferS(void *opaque, uint8_t *data) { ((CDecoder*)opaque)->RelBuffer(data); } @@ -491,8 +489,9 @@ bool CDXVAContext::GetConfig(const D3D11_VIDEO_DECODER_DESC *format, D3D11_VIDEO return true; } -bool CDXVAContext::CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int count, unsigned int alignment, ID3D11Texture2D **texture, ID3D11VideoDecoderOutputView **surfaces) +bool CDXVAContext::CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int count, unsigned int alignment, ID3D11VideoDecoderOutputView **surfaces) { + HRESULT hr = S_OK; ID3D11Device* pDevice = g_Windowing.Get3D11Device(); CD3D11_TEXTURE2D_DESC texDesc(format.OutputFormat, @@ -500,9 +499,10 @@ bool CDXVAContext::CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int FFALIGN(format.SampleHeight, alignment), count, 1, D3D11_BIND_DECODER); - if (FAILED(pDevice->CreateTexture2D(&texDesc, NULL, texture))) + ID3D11Texture2D *texture = nullptr; + if (FAILED(pDevice->CreateTexture2D(&texDesc, NULL, &texture))) { - CLog::Log(LOGNOTICE, "%s - failed creating decoder texture array", __FUNCTION__); + CLog::Log(LOGERROR, "%s - failed creating decoder texture array", __FUNCTION__); return false; } @@ -511,17 +511,26 @@ bool CDXVAContext::CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int vdovDesc.Texture2D.ArraySlice = 0; vdovDesc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D; - for (unsigned i = 0; i < count; ++i) + size_t i; + for (i = 0; i < count; ++i) { vdovDesc.Texture2D.ArraySlice = D3D11CalcSubresource(0, i, texDesc.MipLevels); - if (FAILED(m_service->CreateVideoDecoderOutputView(*texture, &vdovDesc, &surfaces[i]))) + hr = m_service->CreateVideoDecoderOutputView(texture, &vdovDesc, &surfaces[i]); + if (FAILED(hr)) { - CLog::Log(LOGNOTICE, "%s - failed creating surfaces", __FUNCTION__); - return false; + CLog::Log(LOGERROR, "%s - failed creating surfaces", __FUNCTION__); + break; } + } + SAFE_RELEASE(texture); + if (FAILED(hr)) + { + for (size_t j = 0; j < i; ++j) + SAFE_RELEASE(surfaces[j]); } - return true; + + return SUCCEEDED(hr); } bool CDXVAContext::CreateDecoder(D3D11_VIDEO_DECODER_DESC *format, const D3D11_VIDEO_DECODER_CONFIG *config, CDXVADecoderWrapper **decoder) @@ -755,7 +764,6 @@ CDecoder::CDecoder() m_context = (dxva_context*)calloc(1, sizeof(dxva_context)); m_context->cfg = reinterpret_cast<DXVA2_ConfigPictureDecode*>(calloc(1, sizeof(DXVA2_ConfigPictureDecode))); m_context->surface = reinterpret_cast<IDirect3DSurface9**>(calloc(32, sizeof(IDirect3DSurface9*))); - m_viewResource = nullptr; m_surface_alignment = 16; g_Windowing.Register(this); } @@ -794,7 +802,6 @@ void CDecoder::Close() m_dxva_context->Release(this); } m_dxva_context = nullptr; - SAFE_RELEASE(m_viewResource); } static bool CheckH264L41(AVCodecContext *avctx) @@ -1112,7 +1119,7 @@ bool CDecoder::OpenDecoder() CLog::Log(LOGDEBUG, "DXVA - allocating %d surfaces with format %d", m_context->surface_count, m_format.OutputFormat); if (!m_dxva_context->CreateSurfaces(m_format, m_context->surface_count, m_surface_alignment, - &m_viewResource, reinterpret_cast<ID3D11VideoDecoderOutputView**>(m_context->surface))) + reinterpret_cast<ID3D11VideoDecoderOutputView**>(m_context->surface))) return false; for(unsigned i = 0; i < m_context->surface_count; i++) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h index eac792ebd9..b6f42c4450 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h @@ -112,7 +112,7 @@ public: static bool EnsureContext(CDXVAContext **ctx, CDecoder *decoder); bool GetInputAndTarget(int codec, GUID &inGuid, DXGI_FORMAT &outFormat); bool GetConfig(const D3D11_VIDEO_DECODER_DESC *format, D3D11_VIDEO_DECODER_CONFIG &config); - bool CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int count, unsigned int alignment, ID3D11Texture2D **texture, ID3D11VideoDecoderOutputView **surfaces); + bool CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int count, unsigned int alignment, ID3D11VideoDecoderOutputView **surfaces); bool CreateDecoder(D3D11_VIDEO_DECODER_DESC *format, const D3D11_VIDEO_DECODER_CONFIG *config, CDXVADecoderWrapper **decoder); void Release(CDecoder *decoder); ID3D11VideoContext* GetVideoContext() { return m_vcontext; } @@ -186,7 +186,6 @@ protected: unsigned int m_surface_alignment; CCriticalSection m_section; CEvent m_event; - ID3D11Texture2D* m_viewResource; }; }; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp index 8fccb9f79c..e24bbce705 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp @@ -20,6 +20,7 @@ #include "system.h" #ifdef TARGET_DARWIN_OSX #include "osx/CocoaInterface.h" +#include "osx/DarwinUtils.h" #include "DVDVideoCodec.h" #include "DVDCodecs/DVDCodecUtils.h" #include "utils/log.h" @@ -161,6 +162,8 @@ bool CDecoder::Create(AVCodecContext *avctx) CFRelease(config_info); CFRelease(io_surface_properties); CFRelease(cv_pix_fmt); + if (CDarwinUtils::DeviceHasLeakyVDA()) + CFRelease(cv_pix_fmt); CFRelease(buffer_attributes); if(status != kVDADecoderNoErr) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 325057a942..439b4de985 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -18,7 +18,30 @@ * */ +#include "DVDDemuxFFmpeg.h" + +#include <utility> + +#include "commons/Exception.h" +#include "cores/FFmpeg.h" +#include "DVDClock.h" // for DVD_TIME_BASE +#include "DVDDemuxUtils.h" +#include "DVDInputStreams/DVDInputStream.h" +#include "DVDInputStreams/DVDInputStreamFFmpeg.h" +#include "filesystem/CurlFile.h" +#include "filesystem/Directory.h" +#include "filesystem/File.h" +#include "settings/AdvancedSettings.h" +#include "settings/Settings.h" #include "system.h" +#include "threads/SystemClock.h" +#include "URL.h" +#include "utils/log.h" +#include "utils/StringUtils.h" + +#ifdef HAVE_LIBBLURAY +#include "DVDInputStreams/DVDInputStreamBluray.h" +#endif #ifndef __STDC_CONSTANT_MACROS #define __STDC_CONSTANT_MACROS #endif @@ -28,30 +51,12 @@ #ifdef TARGET_POSIX #include "stdint.h" #endif -#include "DVDDemuxFFmpeg.h" -#include "DVDInputStreams/DVDInputStream.h" -#ifdef HAVE_LIBBLURAY -#include "DVDInputStreams/DVDInputStreamBluray.h" -#endif -#include "DVDInputStreams/DVDInputStreamFFmpeg.h" -#include "DVDDemuxUtils.h" -#include "DVDClock.h" // for DVD_TIME_BASE -#include "commons/Exception.h" -#include "settings/AdvancedSettings.h" -#include "settings/Settings.h" -#include "filesystem/File.h" -#include "filesystem/CurlFile.h" -#include "filesystem/Directory.h" -#include "utils/log.h" -#include "threads/SystemClock.h" -#include "utils/StringUtils.h" -#include "URL.h" -#include "cores/FFmpeg.h" extern "C" { #include "libavutil/opt.h" } + struct StereoModeConversionMap { const char* name; diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp index 5a838fda52..2e7ad75c53 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -4784,7 +4784,6 @@ bool CDVDPlayer::SwitchChannel(const CPVRChannelPtr &channel) bool CDVDPlayer::CachePVRStream(void) const { return m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER) && - (!g_PVRManager.IsPlayingRecording() || - (m_item.HasPVRRecordingInfoTag() && m_item.GetPVRRecordingInfoTag()->IsBeingRecorded()))&& + !g_PVRManager.IsPlayingRecording() && g_advancedSettings.m_bPVRCacheInDvdPlayer; } diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h index 1e5f6c9e95..2f0064788d 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.h +++ b/xbmc/cores/dvdplayer/DVDPlayer.h @@ -20,22 +20,22 @@ * */ -#include "cores/IPlayer.h" -#include "threads/Thread.h" +#include <utility> -#include "IDVDPlayer.h" - -#include "DVDMessageQueue.h" +#include "cores/IPlayer.h" #include "DVDClock.h" -#include "DVDPlayerVideo.h" +#include "DVDMessageQueue.h" +#include "DVDPlayerRadioRDS.h" #include "DVDPlayerSubtitle.h" #include "DVDPlayerTeletext.h" -#include "DVDPlayerRadioRDS.h" - +#include "DVDPlayerVideo.h" #include "Edl.h" #include "FileItem.h" -#include "utils/StreamDetails.h" +#include "IDVDPlayer.h" +#include "system.h" #include "threads/SystemClock.h" +#include "threads/Thread.h" +#include "utils/StreamDetails.h" #ifdef HAS_OMXPLAYER #include "OMXCore.h" @@ -43,6 +43,7 @@ #include "linux/RBP.h" #else + // dummy class to avoid ifdefs where calls are made class OMXClock { diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h index 1122a1dca5..014574d7be 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h @@ -19,16 +19,16 @@ */ #pragma once -#include "threads/Thread.h" +#include <list> +#include <utility> #include "DVDAudio.h" #include "DVDClock.h" #include "DVDMessageQueue.h" #include "DVDStreamInfo.h" -#include "utils/BitstreamStats.h" #include "IDVDPlayer.h" - -#include <list> +#include "threads/Thread.h" +#include "utils/BitstreamStats.h" class CDVDPlayer; class CDVDAudioCodec; diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp index 17dee9ce4c..87cfb78158 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -1108,10 +1108,10 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) if (m_speed < 0) { double sleepTime, renderPts; - int bufferLevel; + int queued, discard; double inputPts = m_droppingStats.m_lastPts; - g_renderManager.GetStats(sleepTime, renderPts, bufferLevel); - if (pts_org > renderPts || bufferLevel > 0) + g_renderManager.GetStats(sleepTime, renderPts, queued, discard); + if (pts_org > renderPts || queued > 0) { if (inputPts >= renderPts) { @@ -1130,8 +1130,9 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) else if (m_speed > DVD_PLAYSPEED_NORMAL) { double sleepTime, renderPts; - int bufferLevel; - g_renderManager.GetStats(sleepTime, renderPts, bufferLevel); + int bufferLevel, queued, discard; + g_renderManager.GetStats(sleepTime, renderPts, queued, discard); + bufferLevel = queued + discard; // estimate the time it will take for the next frame to get rendered // drop the frame if it's late in regard to this estimation @@ -1252,10 +1253,10 @@ void CDVDPlayerVideo::ResetFrameRateCalc() double CDVDPlayerVideo::GetCurrentPts() { double iSleepTime, iRenderPts; - int iBufferLevel; + int queued, discard; // get render stats - g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); + g_renderManager.GetStats(iSleepTime, iRenderPts, queued, discard); if (iRenderPts == DVD_NOPTS_VALUE) return DVD_NOPTS_VALUE; @@ -1365,6 +1366,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts, bool updateOnly) bool bNewFrame; int iDroppedPics = -1; int iBufferLevel; + int queued, discard; m_droppingStats.m_lastPts = pts; @@ -1375,7 +1377,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts, bool updateOnly) iDecoderPts = pts; // get render stats - g_renderManager.GetStats(iSleepTime, iRenderPts, iBufferLevel); + g_renderManager.GetStats(iSleepTime, iRenderPts, queued, discard); + iBufferLevel = queued + discard; if (iBufferLevel < 0) result |= EOS_BUFFER_LEVEL; diff --git a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp index ee4170d4e7..4a6c8a8d8e 100644 --- a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp +++ b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp @@ -27,7 +27,6 @@ #include "FileItem.h" #include "profiles/ProfilesManager.h" #include "settings/AdvancedSettings.h" -#include "utils/AutoPtrHandle.h" #include "PlayerCoreConfig.h" #include "PlayerSelectionRule.h" #include "guilib/LocalizeStrings.h" @@ -36,8 +35,6 @@ #define PLAYERCOREFACTORY_XML "playercorefactory.xml" -using namespace AUTOPTR; - CPlayerCoreFactory::CPlayerCoreFactory() { } diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp index 03a5c76dc3..8787a632e8 100644 --- a/xbmc/dbwrappers/Database.cpp +++ b/xbmc/dbwrappers/Database.cpp @@ -23,7 +23,6 @@ #include "filesystem/SpecialProtocol.h" #include "filesystem/File.h" #include "profiles/ProfilesManager.h" -#include "utils/AutoPtrHandle.h" #include "utils/log.h" #include "utils/SortUtils.h" #include "utils/StringUtils.h" @@ -35,7 +34,6 @@ #include "mysqldataset.h" #endif -using namespace AUTOPTR; using namespace dbiplus; #define MAX_COMPRESS_COUNT 20 @@ -150,7 +148,7 @@ std::string CDatabase::GetSingleValue(const std::string &query, std::unique_ptr< if (!m_pDB.get() || !ds.get()) return ret; - if (ds->query(query.c_str()) && ds->num_rows() > 0) + if (ds->query(query) && ds->num_rows() > 0) ret = ds->fv(0).get_asString(); ds->close(); @@ -221,7 +219,7 @@ bool CDatabase::ExecuteQuery(const std::string &strQuery) { if (NULL == m_pDB.get()) return bReturn; if (NULL == m_pDS.get()) return bReturn; - m_pDS->exec(strQuery.c_str()); + m_pDS->exec(strQuery); bReturn = true; } catch (...) @@ -244,7 +242,7 @@ bool CDatabase::ResultQuery(const std::string &strQuery) std::string strPreparedQuery = PrepareSQL(strQuery.c_str()); - bReturn = m_pDS->query(strPreparedQuery.c_str()); + bReturn = m_pDS->query(strPreparedQuery); } catch (...) { @@ -608,7 +606,7 @@ bool CDatabase::Compress(bool bForce /* =true */) iCount = -1; m_pDS->close(); std::string strSQL=PrepareSQL("update version set iCompressCount=%i\n",++iCount); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); if (iCount != 0) return true; } @@ -685,7 +683,7 @@ bool CDatabase::CreateDatabase() CLog::Log(LOGINFO, "creating version table"); m_pDS->exec("CREATE TABLE version (idVersion integer, iCompressCount integer)\n"); std::string strSQL=PrepareSQL("INSERT INTO version (idVersion,iCompressCount) values(%i,0)\n", GetSchemaVersion()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); CreateTables(); CreateAnalytics(); @@ -703,7 +701,7 @@ bool CDatabase::CreateDatabase() void CDatabase::UpdateVersionNumber() { std::string strSQL=PrepareSQL("UPDATE version SET idVersion=%i\n", GetSchemaVersion()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } bool CDatabase::BuildSQL(const std::string &strQuery, const Filter &filter, std::string &strSQL) diff --git a/xbmc/dbwrappers/mysqldataset.cpp b/xbmc/dbwrappers/mysqldataset.cpp index fdb0f5f154..ec8eb0f60b 100644 --- a/xbmc/dbwrappers/mysqldataset.cpp +++ b/xbmc/dbwrappers/mysqldataset.cpp @@ -1597,7 +1597,7 @@ void MysqlDataset::open(const std::string &sql) { void MysqlDataset::open() { if (select_sql.size()) { - query(select_sql.c_str()); + query(select_sql); } else { diff --git a/xbmc/dbwrappers/sqlitedataset.cpp b/xbmc/dbwrappers/sqlitedataset.cpp index 96cf17b2bf..c567f591bc 100644 --- a/xbmc/dbwrappers/sqlitedataset.cpp +++ b/xbmc/dbwrappers/sqlitedataset.cpp @@ -706,7 +706,7 @@ void SqliteDataset::open(const std::string &sql) { void SqliteDataset::open() { if (select_sql.size()) { - query(select_sql.c_str()); + query(select_sql); } else { ds_state = dsInactive; diff --git a/xbmc/dialogs/GUIDialogContextMenu.h b/xbmc/dialogs/GUIDialogContextMenu.h index c5bb40afec..88b34a51fc 100644 --- a/xbmc/dialogs/GUIDialogContextMenu.h +++ b/xbmc/dialogs/GUIDialogContextMenu.h @@ -20,8 +20,11 @@ * */ +#include <utility> + #include "guilib/GUIDialog.h" + class CMediaSource; enum CONTEXT_BUTTON { CONTEXT_BUTTON_CANCELLED = 0, diff --git a/xbmc/dialogs/GUIDialogMediaFilter.h b/xbmc/dialogs/GUIDialogMediaFilter.h index 64f7fbf909..b6f5647edb 100644 --- a/xbmc/dialogs/GUIDialogMediaFilter.h +++ b/xbmc/dialogs/GUIDialogMediaFilter.h @@ -21,6 +21,7 @@ #include <map> #include <string> +#include <utility> #include "dbwrappers/Database.h" #include "dbwrappers/DatabaseQuery.h" diff --git a/xbmc/dialogs/GUIDialogNumeric.cpp b/xbmc/dialogs/GUIDialogNumeric.cpp index 7759d711e1..6c56d3fe47 100644 --- a/xbmc/dialogs/GUIDialogNumeric.cpp +++ b/xbmc/dialogs/GUIDialogNumeric.cpp @@ -19,6 +19,9 @@ */ #include "GUIDialogNumeric.h" + +#include <cassert> + #include "guilib/GUILabelControl.h" #include "utils/md5.h" #include "guilib/GUIWindowManager.h" @@ -41,16 +44,15 @@ CGUIDialogNumeric::CGUIDialogNumeric(void) - : CGUIDialog(WINDOW_DIALOG_NUMERIC, "DialogNumeric.xml") + : CGUIDialog(WINDOW_DIALOG_NUMERIC, "DialogNumeric.xml") + , m_bConfirmed{false} + , m_bCanceled{false} + , m_mode{INPUT_PASSWORD} + , m_block{0} + , m_lastblock{0} + , m_dirty{false} { - m_bConfirmed = false; - m_bCanceled = false; - - m_mode = INPUT_PASSWORD; - m_block = 0; - m_lastblock = 0; memset(&m_datetime, 0, sizeof(SYSTEMTIME)); - m_dirty = false; m_loadType = KEEP_IN_MEMORY; } @@ -89,10 +91,10 @@ void CGUIDialogNumeric::OnInitWindow() } const CGUIControl *control = GetControl(CONTROL_HEADING_LABEL); - if (control != NULL) + if (control != nullptr) data["title"] = control->GetDescription(); - data["value"] = GetOutput(); + data["value"] = GetOutputString(); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Input, "xbmc", "OnInputRequested", data); } @@ -117,24 +119,34 @@ bool CGUIDialogNumeric::OnAction(const CAction &action) else if (action.GetID() >= REMOTE_0 && action.GetID() <= REMOTE_9) OnNumber(action.GetID() - REMOTE_0); else if (action.GetID() >= KEY_VKEY && action.GetID() < KEY_ASCII) - { // input from the keyboard (vkey, not ascii) - BYTE b = action.GetID() & 0xFF; - if (b == XBMCVK_LEFT) OnPrevious(); - else if (b == XBMCVK_RIGHT) OnNext(); - else if (b == XBMCVK_RETURN || b == XBMCVK_NUMPADENTER) OnOK(); - else if (b == XBMCVK_BACK) OnBackSpace(); - else if (b == XBMCVK_ESCAPE) OnCancel(); + { + // input from the keyboard (vkey, not ascii) + uint8_t b = action.GetID() & 0xFF; + if (b == XBMCVK_LEFT) + OnPrevious(); + else if (b == XBMCVK_RIGHT) + OnNext(); + else if (b == XBMCVK_RETURN || b == XBMCVK_NUMPADENTER) + OnOK(); + else if (b == XBMCVK_BACK) + OnBackSpace(); + else if (b == XBMCVK_ESCAPE) + OnCancel(); } else if (action.GetID() >= KEY_ASCII) // FIXME make it KEY_UNICODE { // input from the keyboard - if (action.GetUnicode() == 10 || action.GetUnicode() == 13) OnOK(); // enter - else if (action.GetUnicode() == 8) OnBackSpace(); // backspace - else if (action.GetUnicode() == 27) OnCancel(); // escape + if (action.GetUnicode() == 10 || action.GetUnicode() == 13) + OnOK(); // enter + else if (action.GetUnicode() == 8) + OnBackSpace(); // backspace + else if (action.GetUnicode() == 27) + OnCancel(); // escape else if (action.GetUnicode() >= 48 && action.GetUnicode() < 58) // number OnNumber(action.GetUnicode() - 48); } else return CGUIDialog::OnAction(action); + return true; } @@ -205,13 +217,13 @@ void CGUIDialogNumeric::OnBackSpace() { if (!m_dirty && m_block) { - m_block--; + --m_block; return; } if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD) { // just go back one character if (!m_number.empty()) - m_number.erase(m_number.size() - 1); + m_number.erase(m_number.length() - 1); } else if (m_mode == INPUT_IP_ADDRESS) { @@ -219,7 +231,7 @@ void CGUIDialogNumeric::OnBackSpace() m_ip[m_block] /= 10; else if (m_block) { - m_block--; + --m_block; m_dirty = false; } } @@ -306,14 +318,9 @@ void CGUIDialogNumeric::FrameMove() unsigned int start = 0; unsigned int end = 0; if (m_mode == INPUT_PASSWORD) - { - for (unsigned int i=0; i < m_number.size(); i++) - strLabel += '*'; - } + strLabel.assign(m_number.length(), '*'); else if (m_mode == INPUT_NUMBER) - { // simple - just render text directly strLabel = m_number; - } else if (m_mode == INPUT_TIME) { // format up the time strLabel = StringUtils::Format("%2d:%02d", m_datetime.wHour, m_datetime.wMinute); @@ -349,234 +356,41 @@ void CGUIDialogNumeric::FrameMove() CGUIDialog::FrameMove(); } -void CGUIDialogNumeric::OnNumber(unsigned int num) +void CGUIDialogNumeric::OnNumber(uint32_t num) { ResetAutoClose(); - if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD) + switch (m_mode) { + case INPUT_NUMBER: + case INPUT_PASSWORD: m_number += num + '0'; - } - else if (m_mode == INPUT_TIME) - { - if (m_block == 0) // hour - { - if (m_dirty) // have input the first digit - { - if (m_datetime.wHour < 2 || num < 4) - { - m_datetime.wHour *= 10; - m_datetime.wHour += num; - } - else - m_datetime.wHour = num; - m_block = 1; // move to minutes - m_dirty = false; - } - else // this is the first digit - { - m_datetime.wHour = num; - if (num > 2) - { - m_block = 1; // move to minutes - m_dirty = false; - } - else - m_dirty = true; - } - } - else // minute - { - if (m_dirty) // have input the first digit - { - m_datetime.wMinute *= 10; - m_datetime.wMinute += num; - m_block = 0; // move to hours - m_dirty = false; - } - else // this is the first digit - { - m_datetime.wMinute = num; - if (num > 5) - { - m_block = 0; // move to hours - m_dirty = false; - } - else - m_dirty = true; - } - } - } - else if (m_mode == INPUT_TIME_SECONDS) - { - if (m_block == 0) // hour - { - if (m_dirty) // have input the first digit - { - m_datetime.wHour *= 10; - m_datetime.wHour += num; - m_block = 1; // move to minutes - allows up to 99 hours - m_dirty = false; - } - else // this is the first digit - { - m_datetime.wHour = num; - m_dirty = true; - } - } - else if (m_block == 1) // minute - { - if (m_dirty) // have input the first digit - { - m_datetime.wMinute *= 10; - m_datetime.wMinute += num; - m_block = 2; // move to seconds - allows up to 99 minutes - m_dirty = false; - } - else // this is the first digit - { - m_datetime.wMinute = num; - if (num > 5) - { - m_block = 2; // move to seconds - m_dirty = false; - } - else - m_dirty = true; - } - } - else // seconds - { - if (m_dirty) // have input the first digit - { - m_datetime.wSecond *= 10; - m_datetime.wSecond += num; - m_block = 0; // move to hours - m_dirty = false; - } - else // this is the first digit - { - m_datetime.wSecond = num; - if (num > 5) - { - m_block = 0; // move to hours - m_dirty = false; - } - else - m_dirty = true; - } - } - } - else if (m_mode == INPUT_DATE) - { - if (m_block == 0) // day of month - { - if (m_dirty && (m_datetime.wDay < 3 || num < 2)) - { - m_datetime.wDay *= 10; - m_datetime.wDay += num; - } - else - m_datetime.wDay = num; - if (m_datetime.wDay > 3) - { - m_block = 1; // move to months - m_dirty = false; - } - else - m_dirty = true; - } - else if (m_block == 1) // months - { - if (m_dirty && num < 3) - { - m_datetime.wMonth *= 10; - m_datetime.wMonth += num; - } - else - m_datetime.wMonth = num; - if (m_datetime.wMonth > 1) - { - VerifyDate(false); - m_block = 2; // move to year - m_dirty = false; - } - else - m_dirty = true; - } - else // year - { - if (m_dirty && m_datetime.wYear < 1000) // have taken input - { - m_datetime.wYear *= 10; - m_datetime.wYear += num; - } - else - m_datetime.wYear = num; - if (m_datetime.wYear > 1000) - { - VerifyDate(true); - m_block = 0; // move to day of month - m_dirty = false; - } - else - m_dirty = true; - } - } - else if (m_mode == INPUT_IP_ADDRESS) - { - if (m_dirty && ((m_ip[m_block] < 25) || (m_ip[m_block] == 25 && num < 6) || !(m_block==0 && num==0))) - { - m_ip[m_block] *= 10; - m_ip[m_block] += num; - } - else - m_ip[m_block] = num; - if (m_ip[m_block] > 25 || (m_ip[m_block] == 0 && num == 0)) - { - m_block++; - if (m_block > 3) m_block = 0; - m_dirty = false; - } - else - m_dirty = true; + break; + case INPUT_TIME: + HandleInputTime(num); + break; + case INPUT_TIME_SECONDS: + HandleInputSeconds(num); + break; + case INPUT_DATE: + HandleInputDate(num); + break; + case INPUT_IP_ADDRESS: + HandleInputIP(num); + break; } } -void CGUIDialogNumeric::SetMode(INPUT_MODE mode, void *initial) +void CGUIDialogNumeric::SetMode(INPUT_MODE mode, const SYSTEMTIME &initial) { m_mode = mode; m_block = 0; m_lastblock = 0; if (m_mode == INPUT_TIME || m_mode == INPUT_TIME_SECONDS || m_mode == INPUT_DATE) { - m_datetime = *(SYSTEMTIME *)initial; + m_datetime = initial; m_lastblock = (m_mode != INPUT_TIME) ? 2 : 1; } - else if (m_mode == INPUT_IP_ADDRESS) - { - m_lastblock = 3; - m_ip[0] = m_ip[1] = m_ip[2] = m_ip[3] = 0; - // copy ip string into numeric form - std::string ip = *(std::string *)initial; - unsigned int block = 0; - for (unsigned int i=0; i < ip.size(); i++) - { - if (ip[i] == '.') - { - block++; - if (block > m_lastblock) - break; - } - else if (isdigit(ip[i])) - { - m_ip[block] *= 10; - m_ip[block] += ip[i] - '0'; - } - } - } - else if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD) - m_number = *(std::string *)initial; } void CGUIDialogNumeric::SetMode(INPUT_MODE mode, const std::string &initial) @@ -592,7 +406,7 @@ void CGUIDialogNumeric::SetMode(INPUT_MODE mode, const std::string &initial) // check if we have a pure number if (initial.find_first_not_of("0123456789") == std::string::npos) { - long seconds = strtol(initial.c_str(), NULL, 10); + long seconds = strtol(initial.c_str(), nullptr, 10); dateTime = seconds; } else @@ -600,7 +414,7 @@ void CGUIDialogNumeric::SetMode(INPUT_MODE mode, const std::string &initial) std::string tmp = initial; // if we are handling seconds and if the string only contains // "mm:ss" we need to add dummy "hh:" to get "hh:mm:ss" - if (m_mode == INPUT_TIME_SECONDS && tmp.size() <= 5) + if (m_mode == INPUT_TIME_SECONDS && tmp.length() <= 5) tmp = "00:" + tmp; dateTime.SetFromDBTime(tmp); } @@ -618,33 +432,49 @@ void CGUIDialogNumeric::SetMode(INPUT_MODE mode, const std::string &initial) dateTime.GetAsSystemTime(m_datetime); m_lastblock = (m_mode == INPUT_DATE) ? 2 : 1; } - else - SetMode(mode, (void*)&initial); + else if (m_mode == INPUT_IP_ADDRESS) + { + auto blocks = StringUtils::Split(initial, '.'); + if (blocks.size() != 4) + return; + + for (size_t i = 0; i < blocks.size(); ++i) + { + if (blocks[i].length() > 3) + return; + + m_ip[i] = static_cast<uint8_t>(atoi(blocks[i].c_str())); + } + } + else if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD) + m_number = initial; } -void CGUIDialogNumeric::GetOutput(void *output) const +SYSTEMTIME CGUIDialogNumeric::GetOutput() const { - if (!output) return; - if (m_mode == INPUT_TIME || m_mode == INPUT_TIME_SECONDS || m_mode == INPUT_DATE) - memcpy(output, &m_datetime, sizeof(m_datetime)); - else if (m_mode == INPUT_IP_ADDRESS) - *(std::string *)output = StringUtils::Format("%d.%d.%d.%d", m_ip[0], m_ip[1], m_ip[2], m_ip[3]); - else if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD) - *(std::string *)output = m_number; + assert(m_mode == INPUT_TIME || m_mode == INPUT_TIME_SECONDS || m_mode == INPUT_DATE); + return m_datetime; } -std::string CGUIDialogNumeric::GetOutput() const +std::string CGUIDialogNumeric::GetOutputString() const { - std::string output; - if (m_mode == INPUT_DATE) - output = StringUtils::Format("%02i/%02i/%04i", m_datetime.wDay, m_datetime.wMonth, m_datetime.wYear); - else if (m_mode == INPUT_TIME) - output = StringUtils::Format("%i:%02i", m_datetime.wHour, m_datetime.wMinute); - else if (m_mode == INPUT_TIME_SECONDS) - output = StringUtils::Format("%i:%02i:%02i", m_datetime.wHour, m_datetime.wMinute, m_datetime.wSecond); - else - GetOutput(&output); - return output; + switch (m_mode) + { + case INPUT_DATE: + return StringUtils::Format("%02i/%02i/%04i", m_datetime.wDay, m_datetime.wMonth, m_datetime.wYear); + case INPUT_TIME: + return StringUtils::Format("%i:%02i", m_datetime.wHour, m_datetime.wMinute); + case INPUT_TIME_SECONDS: + return StringUtils::Format("%i:%02i:%02i", m_datetime.wHour, m_datetime.wMinute, m_datetime.wSecond); + case INPUT_IP_ADDRESS: + return StringUtils::Format("%d.%d.%d.%d", m_ip[0], m_ip[1], m_ip[2], m_ip[3]); + case INPUT_NUMBER: + case INPUT_PASSWORD: + return m_number; + } + + //should never get here + return std::string(); } bool CGUIDialogNumeric::ShowAndGetSeconds(std::string &timeString, const std::string &heading) @@ -656,12 +486,12 @@ bool CGUIDialogNumeric::ShowAndGetSeconds(std::string &timeString, const std::st time.wHour = seconds / 3600; time.wMinute = (seconds - time.wHour * 3600) / 60; time.wSecond = seconds - time.wHour * 3600 - time.wMinute * 60; - pDialog->SetMode(INPUT_TIME_SECONDS, (void *)&time); + pDialog->SetMode(INPUT_TIME_SECONDS, time); pDialog->SetHeading(heading); pDialog->Open(); if (!pDialog->IsConfirmed() || pDialog->IsCanceled()) return false; - pDialog->GetOutput(&time); + time = pDialog->GetOutput(); seconds = time.wHour * 3600 + time.wMinute * 60 + time.wSecond; timeString = StringUtils::SecondsToTimeString(seconds); return true; @@ -671,12 +501,12 @@ bool CGUIDialogNumeric::ShowAndGetTime(SYSTEMTIME &time, const std::string &head { CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC); if (!pDialog) return false; - pDialog->SetMode(INPUT_TIME, (void *)&time); + pDialog->SetMode(INPUT_TIME, time); pDialog->SetHeading(heading); pDialog->Open(); if (!pDialog->IsConfirmed() || pDialog->IsCanceled()) return false; - pDialog->GetOutput(&time); + time = pDialog->GetOutput(); return true; } @@ -684,12 +514,12 @@ bool CGUIDialogNumeric::ShowAndGetDate(SYSTEMTIME &date, const std::string &head { CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC); if (!pDialog) return false; - pDialog->SetMode(INPUT_DATE, (void *)&date); + pDialog->SetMode(INPUT_DATE, date); pDialog->SetHeading(heading); pDialog->Open(); if (!pDialog->IsConfirmed() || pDialog->IsCanceled()) return false; - pDialog->GetOutput(&date); + date = pDialog->GetOutput(); return true; } @@ -697,12 +527,12 @@ bool CGUIDialogNumeric::ShowAndGetIPAddress(std::string &IPAddress, const std::s { CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC); if (!pDialog) return false; - pDialog->SetMode(INPUT_IP_ADDRESS, (void *)&IPAddress); + pDialog->SetMode(INPUT_IP_ADDRESS, IPAddress); pDialog->SetHeading(heading); pDialog->Open(); if (!pDialog->IsConfirmed() || pDialog->IsCanceled()) return false; - pDialog->GetOutput(&IPAddress); + IPAddress = pDialog->GetOutputString(); return true; } @@ -712,7 +542,7 @@ bool CGUIDialogNumeric::ShowAndGetNumber(std::string& strInput, const std::strin CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC); pDialog->SetHeading( strHeading ); - pDialog->SetMode(INPUT_NUMBER, (void *)&strInput); + pDialog->SetMode(INPUT_NUMBER, strInput); if (iAutoCloseTimeoutMs) pDialog->SetAutoClose(iAutoCloseTimeoutMs); @@ -720,7 +550,7 @@ bool CGUIDialogNumeric::ShowAndGetNumber(std::string& strInput, const std::strin if (!pDialog->IsAutoClosed() && (!pDialog->IsConfirmed() || pDialog->IsCanceled())) return false; - pDialog->GetOutput(&strInput); + strInput = pDialog->GetOutputString(); return true; } @@ -790,10 +620,10 @@ bool CGUIDialogNumeric::ShowAndVerifyInput(std::string& strToVerify, const std:: std::string strInput; if (!bVerifyInput) strInput = strToVerify; - pDialog->SetMode(INPUT_PASSWORD, (void *)&strInput); + pDialog->SetMode(INPUT_PASSWORD, strInput); pDialog->Open(); - pDialog->GetOutput(&strInput); + strInput = pDialog->GetOutputString(); if (!pDialog->IsConfirmed() || pDialog->IsCanceled()) { @@ -875,3 +705,199 @@ void CGUIDialogNumeric::OnCancel() Close(); } +void CGUIDialogNumeric::HandleInputIP(uint32_t num) +{ + if (m_dirty && ((m_ip[m_block] < 25) || (m_ip[m_block] == 25 && num < 6) || !(m_block == 0 && num == 0))) + { + m_ip[m_block] *= 10; + m_ip[m_block] += num; + } + else + m_ip[m_block] = num; + + if (m_ip[m_block] > 25 || (m_ip[m_block] == 0 && num == 0)) + { + ++m_block; + if (m_block > 3) + m_block = 0; + m_dirty = false; + } + else + m_dirty = true; +} + +void CGUIDialogNumeric::HandleInputDate(uint32_t num) +{ + if (m_block == 0) // day of month + { + if (m_dirty && (m_datetime.wDay < 3 || num < 2)) + { + m_datetime.wDay *= 10; + m_datetime.wDay += num; + } + else + m_datetime.wDay = num; + + if (m_datetime.wDay > 3) + { + m_block = 1; // move to months + m_dirty = false; + } + else + m_dirty = true; + } + else if (m_block == 1) // months + { + if (m_dirty && num < 3) + { + m_datetime.wMonth *= 10; + m_datetime.wMonth += num; + } + else + m_datetime.wMonth = num; + + if (m_datetime.wMonth > 1) + { + VerifyDate(false); + m_block = 2; // move to year + m_dirty = false; + } + else + m_dirty = true; + } + else // year + { + if (m_dirty && m_datetime.wYear < 1000) // have taken input + { + m_datetime.wYear *= 10; + m_datetime.wYear += num; + } + else + m_datetime.wYear = num; + + if (m_datetime.wYear > 1000) + { + VerifyDate(true); + m_block = 0; // move to day of month + m_dirty = false; + } + else + m_dirty = true; + } +} + +void CGUIDialogNumeric::HandleInputSeconds(uint32_t num) +{ + if (m_block == 0) // hour + { + if (m_dirty) // have input the first digit + { + m_datetime.wHour *= 10; + m_datetime.wHour += num; + m_block = 1; // move to minutes - allows up to 99 hours + m_dirty = false; + } + else // this is the first digit + { + m_datetime.wHour = num; + m_dirty = true; + } + } + else if (m_block == 1) // minute + { + if (m_dirty) // have input the first digit + { + m_datetime.wMinute *= 10; + m_datetime.wMinute += num; + m_block = 2; // move to seconds - allows up to 99 minutes + m_dirty = false; + } + else // this is the first digit + { + m_datetime.wMinute = num; + if (num > 5) + { + m_block = 2; // move to seconds + m_dirty = false; + } + else + m_dirty = true; + } + } + else // seconds + { + if (m_dirty) // have input the first digit + { + m_datetime.wSecond *= 10; + m_datetime.wSecond += num; + m_block = 0; // move to hours + m_dirty = false; + } + else // this is the first digit + { + m_datetime.wSecond = num; + if (num > 5) + { + m_block = 0; // move to hours + m_dirty = false; + } + else + m_dirty = true; + } + } +} + +void CGUIDialogNumeric::HandleInputTime(uint32_t num) +{ + if (m_block == 0) // hour + { + if (m_dirty) // have input the first digit + { + if (m_datetime.wHour < 2 || num < 4) + { + m_datetime.wHour *= 10; + m_datetime.wHour += num; + } + else + m_datetime.wHour = num; + + m_block = 1; // move to minutes + m_dirty = false; + } + else // this is the first digit + { + m_datetime.wHour = num; + + if (num > 2) + { + m_block = 1; // move to minutes + m_dirty = false; + } + else + m_dirty = true; + } + } + else // minute + { + if (m_dirty) // have input the first digit + { + m_datetime.wMinute *= 10; + m_datetime.wMinute += num; + m_block = 0; // move to hours + m_dirty = false; + } + else // this is the first digit + { + m_datetime.wMinute = num; + + if (num > 5) + { + m_block = 0; // move to hours + m_dirty = false; + } + else + m_dirty = true; + } + } +} + diff --git a/xbmc/dialogs/GUIDialogNumeric.h b/xbmc/dialogs/GUIDialogNumeric.h index 637c2ea9bb..8923f66ce4 100644 --- a/xbmc/dialogs/GUIDialogNumeric.h +++ b/xbmc/dialogs/GUIDialogNumeric.h @@ -20,6 +20,7 @@ * */ +#include <cstdint> #include "guilib/GUIDialog.h" class CGUIDialogNumeric : @@ -43,10 +44,10 @@ public: static bool ShowAndVerifyInput(std::string& strPassword, const std::string& strHeading, bool bGetUserInput); void SetHeading(const std::string &strHeading); - void SetMode(INPUT_MODE mode, void *initial); + void SetMode(INPUT_MODE mode, const SYSTEMTIME &initial); void SetMode(INPUT_MODE mode, const std::string &initial); - void GetOutput(void *output) const; - std::string GetOutput() const; + SYSTEMTIME GetOutput() const; + std::string GetOutputString() const; static bool ShowAndGetTime(SYSTEMTIME &time, const std::string &heading); static bool ShowAndGetDate(SYSTEMTIME &date, const std::string &heading); @@ -58,7 +59,7 @@ protected: virtual void OnInitWindow(); virtual void OnDeinitWindow(int nextWindowID); - void OnNumber(unsigned int num); + void OnNumber(uint32_t num); void VerifyDate(bool checkYear); void OnNext(); void OnPrevious(); @@ -66,14 +67,19 @@ protected: void OnOK(); void OnCancel(); + void HandleInputIP(uint32_t num); + void HandleInputDate(uint32_t num); + void HandleInputSeconds(uint32_t num); + void HandleInputTime(uint32_t num); + bool m_bConfirmed; bool m_bCanceled; INPUT_MODE m_mode; // the current input mode SYSTEMTIME m_datetime; // for time and date modes - WORD m_ip[4]; // for ip address mode - unsigned int m_block; // for time, date, and IP methods. - unsigned int m_lastblock; + uint8_t m_ip[4]; // for ip address mode + uint32_t m_block; // for time, date, and IP methods. + uint32_t m_lastblock; bool m_dirty; // true if the current block has been changed. std::string m_number; ///< for number or password input }; diff --git a/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp b/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp index 51785a9b9b..ab04494890 100644 --- a/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp +++ b/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp @@ -19,20 +19,23 @@ */ #include "GUIDialogSmartPlaylistEditor.h" + +#include <utility> + +#include "FileItem.h" +#include "filesystem/File.h" +#include "GUIDialogSmartPlaylistRule.h" #include "guilib/GUIKeyboardFactory.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "input/Key.h" +#include "profiles/ProfilesManager.h" +#include "settings/Settings.h" #include "Util.h" #include "utils/SortUtils.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" -#include "GUIDialogSmartPlaylistRule.h" -#include "guilib/GUIWindowManager.h" -#include "filesystem/File.h" -#include "profiles/ProfilesManager.h" -#include "settings/Settings.h" -#include "FileItem.h" -#include "input/Key.h" -#include "guilib/LocalizeStrings.h" #define CONTROL_HEADING 2 #define CONTROL_RULE_LIST 10 diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp index e0f7a66dcc..0e20c98099 100644 --- a/xbmc/epg/Epg.cpp +++ b/xbmc/epg/Epg.cpp @@ -18,17 +18,21 @@ * */ +#include "Epg.h" + +#include <utility> + #include "addons/include/xbmc_epg_types.h" +#include "EpgContainer.h" +#include "EpgDatabase.h" #include "guilib/LocalizeStrings.h" -#include "pvr/PVRManager.h" #include "pvr/addons/PVRClients.h" +#include "pvr/PVRManager.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "threads/SingleLock.h" #include "utils/log.h" -#include "EpgDatabase.h" -#include "EpgContainer.h" using namespace PVR; using namespace EPG; diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index 6224bd1978..cf53ff2277 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -18,12 +18,18 @@ * */ +#include "EpgContainer.h" + +#include <utility> + #include "Application.h" #include "dialogs/GUIDialogExtendedProgressBar.h" +#include "Epg.h" +#include "EpgSearchFilter.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" -#include "pvr/PVRManager.h" #include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/PVRManager.h" #include "pvr/recordings/PVRRecordings.h" #include "settings/AdvancedSettings.h" #include "settings/lib/Setting.h" @@ -31,9 +37,6 @@ #include "threads/SingleLock.h" #include "utils/log.h" -#include "Epg.h" -#include "EpgContainer.h" -#include "EpgSearchFilter.h" using namespace EPG; using namespace PVR; diff --git a/xbmc/epg/EpgDatabase.cpp b/xbmc/epg/EpgDatabase.cpp index 6516c9c702..da1ccf6d33 100644 --- a/xbmc/epg/EpgDatabase.cpp +++ b/xbmc/epg/EpgDatabase.cpp @@ -79,7 +79,8 @@ void CEpgDatabase::CreateTables(void) "iSeriesId integer, " "iEpisodeId integer, " "iEpisodePart integer, " - "sEpisodeName varchar(128)" + "sEpisodeName varchar(128), " + "iFlags integer" ")" ); CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__); @@ -114,6 +115,11 @@ void CEpgDatabase::UpdateTables(int iVersion) m_pDS->exec("ALTER TABLE epgtags ADD iYear integer;"); m_pDS->exec("ALTER TABLE epgtags ADD sIMDBNumber varchar(50);"); } + + if (iVersion < 11) + { + m_pDS->exec("ALTER TABLE epgtags ADD iFlags integer;"); + } } bool CEpgDatabase::DeleteEpg(void) @@ -252,6 +258,7 @@ int CEpgDatabase::Get(CEpg &epg) newTag->m_strEpisodeName = m_pDS->fv("sEpisodeName").get_asString().c_str(); newTag->m_iSeriesNumber = m_pDS->fv("iSeriesId").get_asInt(); newTag->m_strIconPath = m_pDS->fv("sIconPath").get_asString().c_str(); + newTag->m_iFlags = m_pDS->fv("iFlags").get_asInt(); epg.AddEntry(*newTag); ++iReturn; @@ -358,14 +365,14 @@ int CEpgDatabase::Persist(const CEpgInfoTag &tag, bool bSingleUpdate /* = true * strQuery = PrepareSQL("REPLACE INTO epgtags (idEpg, iStartTime, " "iEndTime, sTitle, sPlotOutline, sPlot, sOriginalTitle, sCast, sDirector, sWriter, iYear, sIMDBNumber, " "sIconPath, iGenreType, iGenreSubType, sGenre, iFirstAired, iParentalRating, iStarRating, bNotify, iSeriesId, " - "iEpisodeId, iEpisodePart, sEpisodeName, iBroadcastUid) " - "VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i);", + "iEpisodeId, iEpisodePart, sEpisodeName, iFlags, iBroadcastUid) " + "VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i, %i);", tag.EpgID(), iStartTime, iEndTime, tag.Title(true).c_str(), tag.PlotOutline(true).c_str(), tag.Plot(true).c_str(), tag.OriginalTitle(true).c_str(), tag.Cast().c_str(), tag.Director().c_str(), tag.Writer().c_str(), tag.Year(), tag.IMDBNumber().c_str(), tag.Icon().c_str(), tag.GenreType(), tag.GenreSubType(), strGenre.c_str(), iFirstAired, tag.ParentalRating(), tag.StarRating(), tag.Notify(), - tag.SeriesNumber(), tag.EpisodeNumber(), tag.EpisodePart(), tag.EpisodeName().c_str(), + tag.SeriesNumber(), tag.EpisodeNumber(), tag.EpisodePart(), tag.EpisodeName().c_str(), tag.Flags(), tag.UniqueBroadcastID()); } else @@ -373,14 +380,14 @@ int CEpgDatabase::Persist(const CEpgInfoTag &tag, bool bSingleUpdate /* = true * strQuery = PrepareSQL("REPLACE INTO epgtags (idEpg, iStartTime, " "iEndTime, sTitle, sPlotOutline, sPlot, sOriginalTitle, sCast, sDirector, sWriter, iYear, sIMDBNumber, " "sIconPath, iGenreType, iGenreSubType, sGenre, iFirstAired, iParentalRating, iStarRating, bNotify, iSeriesId, " - "iEpisodeId, iEpisodePart, sEpisodeName, iBroadcastUid, idBroadcast) " - "VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i, %i);", + "iEpisodeId, iEpisodePart, sEpisodeName, iFlags, iBroadcastUid, idBroadcast) " + "VALUES (%u, %u, %u, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, %i, %i, %i, '%s', %i, %i, %i);", tag.EpgID(), iStartTime, iEndTime, tag.Title(true).c_str(), tag.PlotOutline(true).c_str(), tag.Plot(true).c_str(), tag.OriginalTitle(true).c_str(), tag.Cast().c_str(), tag.Director().c_str(), tag.Writer().c_str(), tag.Year(), tag.IMDBNumber().c_str(), tag.Icon().c_str(), tag.GenreType(), tag.GenreSubType(), strGenre.c_str(), iFirstAired, tag.ParentalRating(), tag.StarRating(), tag.Notify(), - tag.SeriesNumber(), tag.EpisodeNumber(), tag.EpisodePart(), tag.EpisodeName().c_str(), + tag.SeriesNumber(), tag.EpisodeNumber(), tag.EpisodePart(), tag.EpisodeName().c_str(), tag.Flags(), tag.UniqueBroadcastID(), iBroadcastId); } diff --git a/xbmc/epg/EpgDatabase.h b/xbmc/epg/EpgDatabase.h index 757e61f41f..13672b7fec 100644 --- a/xbmc/epg/EpgDatabase.h +++ b/xbmc/epg/EpgDatabase.h @@ -57,7 +57,7 @@ namespace EPG * @brief Get the minimal database version that is required to operate correctly. * @return The minimal database version. */ - virtual int GetSchemaVersion(void) const { return 10; }; + virtual int GetSchemaVersion(void) const { return 11; }; /*! * @brief Get the default sqlite database filename. diff --git a/xbmc/epg/EpgInfoTag.cpp b/xbmc/epg/EpgInfoTag.cpp index 604f4d66b0..567207442a 100644 --- a/xbmc/epg/EpgInfoTag.cpp +++ b/xbmc/epg/EpgInfoTag.cpp @@ -53,7 +53,8 @@ CEpgInfoTag::CEpgInfoTag(void) : m_iEpisodePart(0), m_iUniqueBroadcastID(0), m_iYear(0), - m_epg(NULL) + m_epg(NULL), + m_iFlags(EPG_TAG_FLAG_UNDEFINED) { } @@ -71,6 +72,7 @@ CEpgInfoTag::CEpgInfoTag(CEpg *epg, PVR::CPVRChannelPtr pvrChannel, const std::s m_iYear(0), m_strIconPath(strIconPath), m_epg(epg), + m_iFlags(EPG_TAG_FLAG_UNDEFINED), m_pvrChannel(pvrChannel) { UpdatePath(); @@ -100,6 +102,7 @@ CEpgInfoTag::CEpgInfoTag(const EPG_TAG &data) : m_iEpisodePart = data.iEpisodePartNumber; m_iStarRating = data.iStarRating; m_iYear = data.iYear; + m_iFlags = data.iFlags; SetGenre(data.iGenreType, data.iGenreSubType, data.strGenreDescription); @@ -169,7 +172,8 @@ bool CEpgInfoTag::operator ==(const CEpgInfoTag& right) const m_strIconPath == right.m_strIconPath && m_strFileNameAndPath == right.m_strFileNameAndPath && m_startTime == right.m_startTime && - m_endTime == right.m_endTime); + m_endTime == right.m_endTime && + m_iFlags == right.m_iFlags); } bool CEpgInfoTag::operator !=(const CEpgInfoTag& right) const @@ -211,6 +215,7 @@ void CEpgInfoTag::Serialize(CVariant &value) const value["recording"] = recording ? recording->m_strFileNameAndPath : ""; value["isactive"] = IsActive(); value["wasactive"] = WasActive(); + value["isseries"] = IsSeries(); } CDateTime CEpgInfoTag::GetCurrentPlayingTime() const @@ -605,7 +610,8 @@ bool CEpgInfoTag::Update(const CEpgInfoTag &tag, bool bUpdateBroadcastId /* = tr m_iUniqueBroadcastID != tag.m_iUniqueBroadcastID || EpgID() != tag.EpgID() || m_genre != tag.m_genre || - m_strIconPath != tag.m_strIconPath + m_strIconPath != tag.m_strIconPath || + m_iFlags != tag.m_iFlags ); if (bUpdateBroadcastId) bChanged |= (m_iBroadcastId != tag.m_iBroadcastId); @@ -629,6 +635,7 @@ bool CEpgInfoTag::Update(const CEpgInfoTag &tag, bool bUpdateBroadcastId /* = tr m_iGenreType = tag.m_iGenreType; m_iGenreSubType = tag.m_iGenreSubType; m_epg = tag.m_epg; + m_iFlags = tag.m_iFlags; { CSingleLock lock(m_critSection); diff --git a/xbmc/epg/EpgInfoTag.h b/xbmc/epg/EpgInfoTag.h index 2dec60a7b4..6a52cfe059 100644 --- a/xbmc/epg/EpgInfoTag.h +++ b/xbmc/epg/EpgInfoTag.h @@ -403,6 +403,11 @@ namespace EPG */ bool Update(const CEpgInfoTag &tag, bool bUpdateBroadcastId = true); + /*! + * @brief status function to extract IsSeries boolean from EPG iFlags bitfield + */ + bool IsSeries() const { return (m_iFlags & EPG_TAG_FLAG_IS_SERIES) > 0; } + private: /*! @@ -422,6 +427,11 @@ namespace EPG */ CDateTime GetCurrentPlayingTime(void) const; + /*! + * @brief Return the m_iFlags as an unsigned int bitfield (for database use). + */ + unsigned int Flags() const { return m_iFlags; } + bool m_bNotify; /*!< notify on start */ int m_iBroadcastId; /*!< database ID */ @@ -454,6 +464,8 @@ namespace EPG CEpg * m_epg; /*!< the schedule that this event belongs to */ + unsigned int m_iFlags; /*!< the flags applicable to this EPG entry */ + CCriticalSection m_critSection; PVR::CPVRChannelPtr m_pvrChannel; PVR::CPVRRecordingPtr m_recording; diff --git a/xbmc/epg/EpgSearchFilter.cpp b/xbmc/epg/EpgSearchFilter.cpp index bf9f57f6f5..f5879534fe 100644 --- a/xbmc/epg/EpgSearchFilter.cpp +++ b/xbmc/epg/EpgSearchFilter.cpp @@ -53,7 +53,7 @@ void EpgSearchFilter::Reset() m_iChannelGroup = EPG_SEARCH_UNSET; m_bIgnorePresentTimers = true; m_bIgnorePresentRecordings = true; - m_iUniqueBroadcastId = EPG_SEARCH_UNSET; + m_iUniqueBroadcastId = 0; } bool EpgSearchFilter::MatchGenre(const CEpgInfoTag &tag) const @@ -104,7 +104,7 @@ bool EpgSearchFilter::MatchSearchTerm(const CEpgInfoTag &tag) const bool EpgSearchFilter::MatchBroadcastId(const CEpgInfoTag &tag) const { - if (m_iUniqueBroadcastId != EPG_SEARCH_UNSET) + if (m_iUniqueBroadcastId != 0) return (tag.UniqueBroadcastID() == m_iUniqueBroadcastId); return true; diff --git a/xbmc/epg/EpgSearchFilter.h b/xbmc/epg/EpgSearchFilter.h index 0696068d4b..8d85f4e74d 100644 --- a/xbmc/epg/EpgSearchFilter.h +++ b/xbmc/epg/EpgSearchFilter.h @@ -78,6 +78,6 @@ namespace EPG int m_iChannelGroup; /*!< The group this channel belongs to */ bool m_bIgnorePresentTimers; /*!< True to ignore currently present timers (future recordings), false if not */ bool m_bIgnorePresentRecordings; /*!< True to ignore currently active recordings, false if not */ - int m_iUniqueBroadcastId; /*!< The broadcastid to search for */ + unsigned int m_iUniqueBroadcastId; /*!< The broadcastid to search for */ }; } diff --git a/xbmc/events/EventLog.cpp b/xbmc/events/EventLog.cpp index 9f478abc2c..41edcd4d80 100644 --- a/xbmc/events/EventLog.cpp +++ b/xbmc/events/EventLog.cpp @@ -29,6 +29,8 @@ #include "settings/Settings.h" #include "threads/SingleLock.h" +#include <utility> + std::map<int, std::unique_ptr<CEventLog> > CEventLog::s_eventLogs; CCriticalSection CEventLog::s_critical; diff --git a/xbmc/filesystem/Directorization.h b/xbmc/filesystem/Directorization.h index f42106092e..53d0fc65aa 100644 --- a/xbmc/filesystem/Directorization.h +++ b/xbmc/filesystem/Directorization.h @@ -20,6 +20,7 @@ */ #include <string> +#include <utility> #include <vector> #include "FileItem.h" diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp index ae7447dca7..2d76b659b8 100644 --- a/xbmc/filesystem/FileCache.cpp +++ b/xbmc/filesystem/FileCache.cpp @@ -19,7 +19,6 @@ */ #include "threads/SystemClock.h" -#include "utils/AutoPtrHandle.h" #include "FileCache.h" #include "threads/Thread.h" #include "File.h" @@ -30,6 +29,10 @@ #include "utils/log.h" #include "settings/AdvancedSettings.h" +#if !defined(TARGET_WINDOWS) +#include "linux/ConvUtils.h" //GetLastError() +#endif + #include <cassert> #include <algorithm> #include <memory> diff --git a/xbmc/filesystem/RSSDirectory.cpp b/xbmc/filesystem/RSSDirectory.cpp index 5e25afb088..9420552d3c 100644 --- a/xbmc/filesystem/RSSDirectory.cpp +++ b/xbmc/filesystem/RSSDirectory.cpp @@ -19,20 +19,23 @@ */ #include "RSSDirectory.h" -#include "FileItem.h" + +#include <climits> +#include <utility> + #include "CurlFile.h" +#include "FileItem.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" +#include "threads/SingleLock.h" +#include "URL.h" +#include "utils/HTMLUtil.h" +#include "utils/log.h" +#include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/XBMCTinyXML.h" #include "utils/XMLUtils.h" -#include "utils/HTMLUtil.h" -#include "utils/StringUtils.h" #include "video/VideoInfoTag.h" -#include "utils/log.h" -#include "URL.h" -#include "climits" -#include "threads/SingleLock.h" using namespace XFILE; using namespace MUSIC_INFO; diff --git a/xbmc/filesystem/RarManager.h b/xbmc/filesystem/RarManager.h index c6fb635429..536e7dbcbf 100644 --- a/xbmc/filesystem/RarManager.h +++ b/xbmc/filesystem/RarManager.h @@ -1,6 +1,3 @@ -#if !defined(AFX_RARMANAGER_H__06BA7C2E_3FCA_11D9_8186_0050FC718317__INCLUDED_) -#define AFX_RARMANAGER_H__06BA7C2E_3FCA_11D9_8186_0050FC718317__INCLUDED_ - #pragma once /* * Copyright (C) 2005-2013 Team XBMC @@ -22,10 +19,12 @@ * */ -#include <string> -#include "threads/CriticalSection.h" #include <map> +#include <string> +#include <utility> #include <vector> + +#include "threads/CriticalSection.h" #include "UnrarXLib/UnrarX.hpp" #include "utils/Stopwatch.h" @@ -88,5 +87,4 @@ protected: }; extern CRarManager g_RarManager; -#endif diff --git a/xbmc/filesystem/SMBFile.cpp b/xbmc/filesystem/SMBFile.cpp index 699202ac8c..5a9f910fdb 100644 --- a/xbmc/filesystem/SMBFile.cpp +++ b/xbmc/filesystem/SMBFile.cpp @@ -49,13 +49,17 @@ void xb_smbc_auth(const char *srv, const char *shr, char *wg, int wglen, return ; } +// WTF is this ?, we get the original server cache only +// to set the server cache to this function which call the +// original one anyway. Seems quite silly. smbc_get_cached_srv_fn orig_cache; - SMBCSRV* xb_smbc_cache(SMBCCTX* c, const char* server, const char* share, const char* workgroup, const char* username) { return orig_cache(c, server, share, workgroup, username); } +bool CSMB::IsFirstInit = true; + CSMB::CSMB() { m_IdleTimeout = 0; @@ -135,6 +139,12 @@ void CSMB::Init() // reads smb.conf so this MUST be after we create smb.conf // multiple smbc_init calls are ignored by libsmbclient. + // note: this is important as it initilizes the smb old + // interface compatibility. Samba 3.4.0 or higher has the new interface. + // note: we leak the following here once, not sure why yet. + // 48 bytes -> smb_xmalloc_array + // 32 bytes -> set_param_opt + // 16 bytes -> set_param_opt smbc_init(xb_smbc_auth, 0); // setup our context @@ -147,9 +157,11 @@ void CSMB::Init() smbc_setOptionOneSharePerServer(m_context, false); smbc_setOptionBrowseMaxLmbCount(m_context, 0); smbc_setTimeout(m_context, g_advancedSettings.m_sambaclienttimeout * 1000); + // we do not need to strdup these, smbc_setXXX below will make their own copies if (CSettings::GetInstance().GetString(CSettings::SETTING_SMB_WORKGROUP).length() > 0) - smbc_setWorkgroup(m_context, strdup(CSettings::GetInstance().GetString(CSettings::SETTING_SMB_WORKGROUP).c_str())); - smbc_setUser(m_context, strdup("guest")); + smbc_setWorkgroup(m_context, (char*)CSettings::GetInstance().GetString(CSettings::SETTING_SMB_WORKGROUP).c_str()); + std::string guest = "guest"; + smbc_setUser(m_context, (char*)guest.c_str()); #else m_context->debug = (g_advancedSettings.CanLogComponent(LOGSAMBA) ? 10 : 0); m_context->callbacks.auth_fn = xb_smbc_auth; @@ -158,16 +170,28 @@ void CSMB::Init() m_context->options.one_share_per_server = false; m_context->options.browse_max_lmb_count = 0; m_context->timeout = g_advancedSettings.m_sambaclienttimeout * 1000; + // we need to strdup these, they will get free'ed on smbc_free_context if (CSettings::GetInstance().GetString(CSettings::SETTING_SMB_WORKGROUP).length() > 0) - m_context->workgroup = strdup(CSettings::GetInstance().GetString(CSettings::SETTING_SMB_WORKGROUP).c_str()); - m_context->user = strdup("guest"); + m_context->workgroup = strdup(CSettings::GetInstance().GetString(CSettings::SETTING_SMB_WORKGROUP).c_str())); + m_context->user = strdup("guest")); #endif // initialize samba and do some hacking into the settings if (smbc_init_context(m_context)) { - /* setup old interface to use this context */ - smbc_set_context(m_context); + // setup context using the smb old interface compatibility + SMBCCTX *old_context = smbc_set_context(m_context); + // free previous context or we leak it, this comes from smbc_init above. + // there is a bug in smbclient (old interface), if we init/set a context + // then set(null)/free it in DeInit above, the next smbc_set_context + // return the already freed previous context, free again and bang, crash. + // so we setup a stic bool to track the first init so we can free the + // context associated with the initial smbc_init. + if (old_context && IsFirstInit) + { + smbc_free_context(old_context, 1); + IsFirstInit = false; + } } else { diff --git a/xbmc/filesystem/SMBFile.h b/xbmc/filesystem/SMBFile.h index a04b387e9e..028a5e2544 100644 --- a/xbmc/filesystem/SMBFile.h +++ b/xbmc/filesystem/SMBFile.h @@ -60,6 +60,7 @@ private: #ifdef TARGET_POSIX int m_OpenConnections; unsigned int m_IdleTimeout; + static bool IsFirstInit; #endif }; diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp index 5f0b53344b..8d3c6c457d 100644 --- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp +++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp @@ -50,14 +50,14 @@ using namespace XFILE::VIDEODATABASEDIRECTORY; // Constructor is protected use ParseURL() CDirectoryNode::CDirectoryNode(NODE_TYPE Type, const std::string& strName, CDirectoryNode* pParent) { - m_Type=Type; - m_strName=strName; - m_pParent=pParent; + m_Type = Type; + m_strName = strName; + m_pParent = pParent; } CDirectoryNode::~CDirectoryNode() { - delete m_pParent; + delete m_pParent, m_pParent = nullptr; } // Parses a given path and returns the current node of the path @@ -65,21 +65,23 @@ CDirectoryNode* CDirectoryNode::ParseURL(const std::string& strPath) { CURL url(strPath); - std::string strDirectory=url.GetFileName(); + std::string strDirectory = url.GetFileName(); URIUtils::RemoveSlashAtEnd(strDirectory); - std::vector<std::string> Path = StringUtils::Split(strDirectory, '/'); + std::vector<std::string> Path = StringUtils::Tokenize(strDirectory, '/'); + // we always have a root node, it is special and has a path of "" Path.insert(Path.begin(), ""); - CDirectoryNode* pNode=NULL; - CDirectoryNode* pParent=NULL; - NODE_TYPE NodeType=NODE_TYPE_ROOT; - - for (int i=0; i<(int)Path.size(); ++i) + CDirectoryNode *pNode = nullptr; + CDirectoryNode *pParent = nullptr; + NODE_TYPE NodeType = NODE_TYPE_ROOT; + // loop down the dir path, creating a node with a parent. + // if we hit a child type of NODE_TYPE_NONE, then we are done. + for (size_t i = 0; i < Path.size() && NodeType != NODE_TYPE_NONE; ++i) { - pNode=CDirectoryNode::CreateNode(NodeType, Path[i], pParent); - NodeType= pNode ? pNode->GetChildType() : NODE_TYPE_NONE; - pParent=pNode; + pNode = CDirectoryNode::CreateNode(NodeType, Path[i], pParent); + NodeType = pNode ? pNode->GetChildType() : NODE_TYPE_NONE; + pParent = pNode; } // Add all the additional URL options to the last node @@ -178,7 +180,7 @@ CDirectoryNode* CDirectoryNode::GetParent() const void CDirectoryNode::RemoveParent() { - m_pParent=NULL; + m_pParent = nullptr; } // should be overloaded by a derived class @@ -198,18 +200,18 @@ std::string CDirectoryNode::BuildPath() const array.insert(array.begin(), m_strName); CDirectoryNode* pParent=m_pParent; - while (pParent!=NULL) + while (pParent != NULL) { const std::string& strNodeName=pParent->GetName(); if (!strNodeName.empty()) array.insert(array.begin(), strNodeName); - pParent=pParent->GetParent(); + pParent = pParent->GetParent(); } std::string strPath="videodb://"; - for (int i=0; i<(int)array.size(); ++i) - strPath+=array[i]+"/"; + for (int i = 0; i < (int)array.size(); ++i) + strPath += array[i]+"/"; std::string options = m_options.GetOptionsString(); if (!options.empty()) @@ -234,10 +236,10 @@ void CDirectoryNode::CollectQueryParams(CQueryParams& params) const params.SetQueryParam(m_Type, m_strName); CDirectoryNode* pParent=m_pParent; - while (pParent!=NULL) + while (pParent != NULL) { params.SetQueryParam(pParent->GetType(), pParent->GetName()); - pParent=pParent->GetParent(); + pParent = pParent->GetParent(); } } @@ -260,7 +262,7 @@ bool CDirectoryNode::GetChilds(CFileItemList& items) if (pNode.get()) { pNode->m_options = m_options; - bSuccess=pNode->GetContent(items); + bSuccess = pNode->GetContent(items); if (bSuccess) { AddQueuingFolder(items); diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp index 3dd8d6ddca..d7b76dbfbc 100644 --- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp +++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp @@ -18,11 +18,14 @@ * */ -#include "video/VideoDatabase.h" #include "DirectoryNodeOverview.h" -#include "settings/Settings.h" + +#include <utility> + #include "FileItem.h" #include "guilib/LocalizeStrings.h" +#include "settings/Settings.h" +#include "video/VideoDatabase.h" using namespace XFILE::VIDEODATABASEDIRECTORY; diff --git a/xbmc/filesystem/XbtManager.cpp b/xbmc/filesystem/XbtManager.cpp index 72df2e8f75..7dea05a1e6 100644 --- a/xbmc/filesystem/XbtManager.cpp +++ b/xbmc/filesystem/XbtManager.cpp @@ -19,9 +19,12 @@ */ #include "XbtManager.h" -#include "URL.h" + +#include <utility> + #include "guilib/XBTF.h" #include "guilib/XBTFReader.h" +#include "URL.h" namespace XFILE { diff --git a/xbmc/filesystem/ZipManager.cpp b/xbmc/filesystem/ZipManager.cpp index e68f47d818..c042c38364 100644 --- a/xbmc/filesystem/ZipManager.cpp +++ b/xbmc/filesystem/ZipManager.cpp @@ -18,20 +18,19 @@ * */ -#include "system.h" #include "ZipManager.h" -#include "URL.h" + +#include <algorithm> +#include <utility> + #include "File.h" +#include "system.h" +#include "URL.h" #include "utils/CharsetConverter.h" -#include "utils/log.h" #include "utils/EndianSwap.h" +#include "utils/log.h" #include "utils/URIUtils.h" - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - using namespace XFILE; CZipManager::CZipManager() @@ -101,8 +100,8 @@ bool CZipManager::GetZipList(const CURL& url, std::vector<SZipEntry>& items) // Don't need to look in the last 18 bytes (ECDREC_SIZE-4) // But as we need to do overlapping between blocks (3 bytes), // we start the search at ECDREC_SIZE-1 from the end of file - int searchSize = (int) min(65557, fileSize-ECDREC_SIZE+1); - int blockSize = (int) min(1024, searchSize); + int searchSize = (int) std::min(static_cast<int64_t>(65557), fileSize-ECDREC_SIZE+1); + int blockSize = (int) std::min(1024, searchSize); int nbBlock = searchSize / blockSize; int extraBlockSize = searchSize % blockSize; // Signature is on 4 bytes diff --git a/xbmc/filesystem/win32/Win32File.cpp b/xbmc/filesystem/win32/Win32File.cpp index 4cc4d930a0..9b34595c18 100644 --- a/xbmc/filesystem/win32/Win32File.cpp +++ b/xbmc/filesystem/win32/Win32File.cpp @@ -465,6 +465,12 @@ int CWin32File::Stat(const CURL& url, struct __stat64* statData) return -1; std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); + if (pathnameW.empty()) + { + errno = ENOENT; + return -1; + } + if (pathnameW.length() <= 6) // 6 is length of "\\?\x:" return -1; // pathnameW is empty or points to device ("\\?\x:"), on win32 stat() for devices is not supported diff --git a/xbmc/guilib/GUIBaseContainer.h b/xbmc/guilib/GUIBaseContainer.h index e2ae8cc8dc..aa0f43b80b 100644 --- a/xbmc/guilib/GUIBaseContainer.h +++ b/xbmc/guilib/GUIBaseContainer.h @@ -25,8 +25,10 @@ * */ -#include "IGUIContainer.h" +#include <utility> + #include "GUIListItemLayout.h" +#include "IGUIContainer.h" #include "utils/Stopwatch.h" /*! diff --git a/xbmc/guilib/GUIColorManager.cpp b/xbmc/guilib/GUIColorManager.cpp index 74b88c7cc0..4840033e67 100644 --- a/xbmc/guilib/GUIColorManager.cpp +++ b/xbmc/guilib/GUIColorManager.cpp @@ -19,12 +19,15 @@ */ #include "GUIColorManager.h" -#include "filesystem/SpecialProtocol.h" + +#include <utility> + #include "addons/Skin.h" +#include "filesystem/SpecialProtocol.h" #include "utils/log.h" +#include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/XBMCTinyXML.h" -#include "utils/StringUtils.h" CGUIColorManager g_colorManager; diff --git a/xbmc/guilib/GUIColorManager.h b/xbmc/guilib/GUIColorManager.h index a8af509678..680a3eb732 100644 --- a/xbmc/guilib/GUIColorManager.h +++ b/xbmc/guilib/GUIColorManager.h @@ -33,9 +33,9 @@ \brief */ +#include <stdint.h> #include <map> #include <string> -#include <stdint.h> class CXBMCTinyXML; diff --git a/xbmc/guilib/GUIControlGroup.cpp b/xbmc/guilib/GUIControlGroup.cpp index 41e1024252..10ba9b0a57 100644 --- a/xbmc/guilib/GUIControlGroup.cpp +++ b/xbmc/guilib/GUIControlGroup.cpp @@ -19,9 +19,11 @@ */ #include "GUIControlGroup.h" -#include "guiinfo/GUIInfoLabels.h" #include <cassert> +#include <utility> + +#include "guiinfo/GUIInfoLabels.h" CGUIControlGroup::CGUIControlGroup() { diff --git a/xbmc/guilib/GUIControlGroupList.cpp b/xbmc/guilib/GUIControlGroupList.cpp index 7a89fcd5f5..9f6a1cbe55 100644 --- a/xbmc/guilib/GUIControlGroupList.cpp +++ b/xbmc/guilib/GUIControlGroupList.cpp @@ -81,15 +81,17 @@ void CGUIControlGroupList::Process(unsigned int currentTime, CDirtyRegionList &d g_graphicsContext.SetOrigin(m_posX + pos - m_scroller.GetValue(), m_posY); control->DoProcess(currentTime, dirtyregions); - if (IsControlOnScreen(pos, control)) + if (control->IsVisible()) { - if (control->HasFocus()) - m_focusedPosition = index; - index++; - } + if (IsControlOnScreen(pos, control)) + { + if (control->HasFocus()) + m_focusedPosition = index; + index++; + } - if (control->IsVisible()) pos += Size(control) + m_itemGap; + } g_graphicsContext.RestoreOrigin(); } CGUIControl::Process(currentTime, dirtyregions); diff --git a/xbmc/guilib/GUIDialog.cpp b/xbmc/guilib/GUIDialog.cpp index 841ced0db0..ad3a9b7793 100644 --- a/xbmc/guilib/GUIDialog.cpp +++ b/xbmc/guilib/GUIDialog.cpp @@ -91,10 +91,6 @@ bool CGUIDialog::OnMessage(CGUIMessage& message) { case GUI_MSG_WINDOW_DEINIT: { - CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow()); - if (pWindow) - g_windowManager.ShowOverlay(pWindow->GetOverlayState()); - CGUIWindow::OnMessage(message); return true; } diff --git a/xbmc/guilib/GUIFadeLabelControl.cpp b/xbmc/guilib/GUIFadeLabelControl.cpp index 269b68c79f..ebd435e77d 100644 --- a/xbmc/guilib/GUIFadeLabelControl.cpp +++ b/xbmc/guilib/GUIFadeLabelControl.cpp @@ -82,10 +82,8 @@ void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &d if (m_currentLabel >= m_infoLabels.size() ) m_currentLabel = 0; - bool dirty = false; if (m_textLayout.Update(GetLabel())) { // changed label - update our suffix based on length of available text - dirty = true; float width, height; m_textLayout.GetTextExtent(width, height); float spaceWidth = m_label.font->GetCharWidth(L' '); @@ -105,7 +103,6 @@ void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &d m_scrollInfo.Reset(); m_fadeAnim.QueueAnimation(ANIM_PROCESS_REVERSE); m_lastLabel = m_currentLabel; - dirty = true; } if (m_infoLabels.size() > 1 || !m_shortText) @@ -122,13 +119,16 @@ void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &d } else if (m_scrollInfo.pixelPos > m_scrollInfo.m_textWidth) moveToNextLabel = true; - + + if(m_scrollInfo.pixelSpeed || m_fadeAnim.GetState() == ANIM_STATE_IN_PROCESS) + MarkDirtyRegion(); + // apply the fading animation TransformMatrix matrix; m_fadeAnim.Animate(currentTime, true); m_fadeAnim.RenderAnimation(matrix); m_fadeMatrix = g_graphicsContext.AddTransform(matrix); - + if (m_fadeAnim.GetState() == ANIM_STATE_APPLIED) m_fadeAnim.ResetAnimation(); @@ -142,22 +142,17 @@ void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &d m_currentLabel = 0; m_scrollInfo.Reset(); m_fadeAnim.QueueAnimation(ANIM_PROCESS_REVERSE); - dirty = true; } } if (m_scroll) { - if (m_textLayout.UpdateScrollinfo(m_scrollInfo)) - dirty = true; + m_textLayout.UpdateScrollinfo(m_scrollInfo); } g_graphicsContext.RemoveTransform(); } - if (dirty) - MarkDirtyRegion(); - CGUIControl::Process(currentTime, dirtyregions); } diff --git a/xbmc/guilib/GUIFontManager.h b/xbmc/guilib/GUIFontManager.h index 1a681b07f5..5d1a07b1fd 100644 --- a/xbmc/guilib/GUIFontManager.h +++ b/xbmc/guilib/GUIFontManager.h @@ -28,6 +28,8 @@ * */ +#include <utility> + #include "GraphicContext.h" #include "IMsgTargetCallback.h" #include "utils/GlobalsHandling.h" diff --git a/xbmc/guilib/GUIIncludes.cpp b/xbmc/guilib/GUIIncludes.cpp index 3decd4dddd..de1758395b 100644 --- a/xbmc/guilib/GUIIncludes.cpp +++ b/xbmc/guilib/GUIIncludes.cpp @@ -82,6 +82,7 @@ CGUIIncludes::CGUIIncludes() m_constantNodes.insert("timeperimage"); m_constantNodes.insert("fadetime"); m_constantNodes.insert("pauseatend"); + m_constantNodes.insert("depth"); } CGUIIncludes::~CGUIIncludes() diff --git a/xbmc/guilib/GUIIncludes.h b/xbmc/guilib/GUIIncludes.h index f007d995d5..d758a7f285 100644 --- a/xbmc/guilib/GUIIncludes.h +++ b/xbmc/guilib/GUIIncludes.h @@ -23,7 +23,9 @@ #include <map> #include <set> #include <string> +#include <utility> #include <vector> + #include "interfaces/info/InfoBool.h" // forward definitions diff --git a/xbmc/guilib/GUIListItem.cpp b/xbmc/guilib/GUIListItem.cpp index 09de26f57b..720d54dda1 100644 --- a/xbmc/guilib/GUIListItem.cpp +++ b/xbmc/guilib/GUIListItem.cpp @@ -19,6 +19,9 @@ */ #include "GUIListItem.h" + +#include <utility> + #include "GUIListItemLayout.h" #include "utils/Archive.h" #include "utils/CharsetConverter.h" diff --git a/xbmc/guilib/GUIMultiImage.cpp b/xbmc/guilib/GUIMultiImage.cpp index be2327aa99..cfa63a3532 100644 --- a/xbmc/guilib/GUIMultiImage.cpp +++ b/xbmc/guilib/GUIMultiImage.cpp @@ -49,7 +49,7 @@ CGUIMultiImage::CGUIMultiImage(int parentID, int controlID, float posX, float po } CGUIMultiImage::CGUIMultiImage(const CGUIMultiImage &from) - : CGUIControl(from), m_texturePath(), m_imageTimer(), m_files(), m_image(from.m_image) + : CGUIControl(from), m_texturePath(from.m_texturePath), m_imageTimer(), m_files(), m_image(from.m_image) { m_timePerImage = from.m_timePerImage; m_timeToPauseAtEnd = from.m_timeToPauseAtEnd; diff --git a/xbmc/guilib/GUIStaticItem.h b/xbmc/guilib/GUIStaticItem.h index 57cf5f9194..8ef80c0b15 100644 --- a/xbmc/guilib/GUIStaticItem.h +++ b/xbmc/guilib/GUIStaticItem.h @@ -25,9 +25,11 @@ \brief */ +#include <utility> + +#include "GUIAction.h" #include "GUIInfoTypes.h" #include "xbmc/FileItem.h" -#include "GUIAction.h" class TiXmlElement; diff --git a/xbmc/guilib/GUIWindow.cpp b/xbmc/guilib/GUIWindow.cpp index f718a9d4c6..7f9a4325c8 100644 --- a/xbmc/guilib/GUIWindow.cpp +++ b/xbmc/guilib/GUIWindow.cpp @@ -55,7 +55,6 @@ CGUIWindow::CGUIWindow(int id, const std::string &xmlFile) SetID(id); SetProperty("xmlfile", xmlFile); m_lastControlID = 0; - m_overlayState = OVERLAY_STATE_PARENT_WINDOW; // Use parent or previous window's state m_isDialog = false; m_needsScaling = true; m_windowLoaded = false; @@ -269,12 +268,6 @@ bool CGUIWindow::Load(TiXmlElement* pRootElement) pControl = pControl->NextSiblingElement(); } } - else if (strValue == "allowoverlay") - { - bool overlay = false; - if (XMLUtils::GetBoolean(pRootElement, "allowoverlay", overlay)) - m_overlayState = overlay ? OVERLAY_STATE_SHOWN : OVERLAY_STATE_HIDDEN; - } pChild = pChild->NextSiblingElement(); } @@ -555,7 +548,6 @@ void CGUIWindow::OnInitWindow() RestoreControlStates(); SetInitialVisibility(); QueueAnimation(ANIM_TYPE_WINDOW_OPEN); - g_windowManager.ShowOverlay(m_overlayState); if (!m_manualRunActions) { @@ -1004,7 +996,6 @@ void CGUIWindow::SetDefaults() m_defaultAlways = false; m_defaultControl = 0; m_posX = m_posY = m_width = m_height = 0; - m_overlayState = OVERLAY_STATE_PARENT_WINDOW; // Use parent or previous window's state m_previousWindow = WINDOW_INVALID; m_animations.clear(); m_origins.clear(); diff --git a/xbmc/guilib/GUIWindow.h b/xbmc/guilib/GUIWindow.h index 420441edcb..64af98a349 100644 --- a/xbmc/guilib/GUIWindow.h +++ b/xbmc/guilib/GUIWindow.h @@ -164,10 +164,6 @@ public: // versions of UpdateVisibility, and are deemed visible if they're in // the window manager's active list. - enum OVERLAY_STATE { OVERLAY_STATE_PARENT_WINDOW=0, OVERLAY_STATE_SHOWN, OVERLAY_STATE_HIDDEN }; - - OVERLAY_STATE GetOverlayState() const { return m_overlayState; }; - virtual bool IsAnimating(ANIMATION_TYPE animType); void DisableAnimations(); @@ -241,7 +237,6 @@ protected: void LoadControl(TiXmlElement* pControl, CGUIControlGroup *pGroup, const CRect &rect); std::vector<int> m_idRange; - OVERLAY_STATE m_overlayState; RESOLUTION_INFO m_coordsRes; // resolution that the window coordinates are in. bool m_needsScaling; bool m_windowLoaded; // true if the window's xml file has been loaded diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp index a1b968b479..650169072b 100644 --- a/xbmc/guilib/GUIWindowManager.cpp +++ b/xbmc/guilib/GUIWindowManager.cpp @@ -154,7 +154,6 @@ using namespace KODI::MESSAGING; CGUIWindowManager::CGUIWindowManager(void) { m_pCallback = NULL; - m_bShowOverlay = true; m_iNested = 0; m_initialized = false; } @@ -677,9 +676,6 @@ void CGUIWindowManager::PreviousWindow() // tell our info manager which window we are going to g_infoManager.SetNextWindow(previousWindow); - // set our overlay state (enables out animations on window change) - HideOverlay(pNewWindow->GetOverlayState()); - // deinitialize our window CloseWindowSync(pCurrentWindow); @@ -797,9 +793,6 @@ void CGUIWindowManager::ActivateWindow_Internal(int iWindowID, const std::vector g_infoManager.SetNextWindow(iWindowID); - // set our overlay state - HideOverlay(pNewWindow->GetOverlayState()); - // deactivate any window int currentWindow = GetActiveWindow(); CGUIWindow *pWindow = GetWindow(currentWindow); @@ -1483,26 +1476,6 @@ void CGUIWindowManager::UnloadNotOnDemandWindows() } } -bool CGUIWindowManager::IsOverlayAllowed() const -{ - if (GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO || - GetActiveWindow() == WINDOW_SCREENSAVER) - return false; - return m_bShowOverlay; -} - -void CGUIWindowManager::ShowOverlay(CGUIWindow::OVERLAY_STATE state) -{ - if (state != CGUIWindow::OVERLAY_STATE_PARENT_WINDOW) - m_bShowOverlay = state == CGUIWindow::OVERLAY_STATE_SHOWN; -} - -void CGUIWindowManager::HideOverlay(CGUIWindow::OVERLAY_STATE state) -{ - if (state == CGUIWindow::OVERLAY_STATE_HIDDEN) - m_bShowOverlay = false; -} - void CGUIWindowManager::AddToWindowHistory(int newWindowID) { // Check the window stack to see if this window is in our history, diff --git a/xbmc/guilib/GUIWindowManager.h b/xbmc/guilib/GUIWindowManager.h index 1efe316030..76be88d298 100644 --- a/xbmc/guilib/GUIWindowManager.h +++ b/xbmc/guilib/GUIWindowManager.h @@ -28,14 +28,16 @@ * */ -#include "GUIWindow.h" -#include "IWindowManagerCallback.h" -#include "IMsgTargetCallback.h" +#include <list> +#include <utility> + #include "DirtyRegionTracker.h" -#include "utils/GlobalsHandling.h" #include "guilib/WindowIDs.h" +#include "GUIWindow.h" +#include "IMsgTargetCallback.h" +#include "IWindowManagerCallback.h" #include "messaging/IMessageTarget.h" -#include <list> +#include "utils/GlobalsHandling.h" class CGUIDialog; enum class DialogModalityType; @@ -167,7 +169,6 @@ public: bool IsWindowActive(const std::string &xmlFile, bool ignoreClosing = true) const; bool IsWindowVisible(const std::string &xmlFile) const; bool IsWindowTopMost(const std::string &xmlFile) const; - bool IsOverlayAllowed() const; /*! \brief Checks if the given window is an addon window. * * \return true if the given window is an addon window, otherwise false. @@ -178,7 +179,6 @@ public: * \return true if the given window is a python window, otherwise false. */ bool IsPythonWindow(int id) const { return (id >= WINDOW_PYTHON_START && id <= WINDOW_PYTHON_END); }; - void ShowOverlay(CGUIWindow::OVERLAY_STATE state); void GetActiveModelessWindows(std::vector<int> &ids); #ifdef _DEBUG void DumpTextureUse(); @@ -188,7 +188,6 @@ private: void LoadNotOnDemandWindows(); void UnloadNotOnDemandWindows(); - void HideOverlay(CGUIWindow::OVERLAY_STATE state); void AddToWindowHistory(int newWindowID); void ClearWindowHistory(); void CloseWindowSync(CGUIWindow *window, int nextWindowID = 0); @@ -222,7 +221,6 @@ private: CCriticalSection m_critSection; std::vector <IMsgTargetCallback*> m_vecMsgTargets; - bool m_bShowOverlay; int m_iNested; bool m_initialized; diff --git a/xbmc/guilib/Gif.cpp b/xbmc/guilib/Gif.cpp index 6960070839..6d81b824b9 100644 --- a/xbmc/guilib/Gif.cpp +++ b/xbmc/guilib/Gif.cpp @@ -74,13 +74,11 @@ Gif::Gif() : m_numFrames(0), m_filename(""), m_gif(nullptr), - m_hasBackground(false), m_pTemplate(nullptr), m_isAnimated(-1) { if (!m_dll.Load()) CLog::Log(LOGERROR, "Gif::Gif(): Could not load giflib"); - memset(&m_backColor, 0, sizeof(m_backColor)); m_gifFile = new XFILE::CFile(); } @@ -285,16 +283,6 @@ void Gif::InitTemplateAndColormap() { m_globalPalette.clear(); ConvertColorTable(m_globalPalette, m_gif->SColorMap, m_gif->SColorMap->ColorCount); - - // draw the canvas - m_backColor = m_globalPalette[m_gif->SBackGroundColor]; - m_hasBackground = true; - - for (unsigned int i = 0; i < m_height * m_width; ++i) - { - unsigned char *dest = m_pTemplate + (i *sizeof(GifColor)); - memcpy(dest, &m_backColor, sizeof(GifColor)); - } } else m_globalPalette.clear(); @@ -386,12 +374,17 @@ bool Gif::ExtractFrames(unsigned int count) { frame->m_palette.clear(); ConvertColorTable(frame->m_palette, imageDesc.ColorMap, imageDesc.ColorMap->ColorCount); - // TODO save a backup of the palette for frames without a table in case there's no gloabl table. + // TODO save a backup of the palette for frames without a table in case there's no global table. } else if (m_gif->SColorMap) { frame->m_palette = m_globalPalette; } + else + { + CLog::Log(LOGDEBUG, "Gif::ExtractFrames(): No color map found for frame %d", i); + continue; + } // fill delay, disposal and transparent color into frame if (!GcbToFrame(*frame, i)) @@ -413,6 +406,8 @@ bool Gif::ExtractFrames(unsigned int count) void Gif::ConstructFrame(GifFrame &frame, const unsigned char* src) const { + size_t paletteSize = frame.m_palette.size(); + for (unsigned int dest_y = frame.m_top, src_y = 0; src_y < frame.m_height; ++dest_y, ++src_y) { unsigned char *to = frame.m_pImage + (dest_y * m_pitch) + (frame.m_left * sizeof(GifColor)); @@ -420,18 +415,19 @@ void Gif::ConstructFrame(GifFrame &frame, const unsigned char* src) const const unsigned char *from = src + (src_y * frame.m_width); for (unsigned int src_x = 0; src_x < frame.m_width; ++src_x) { - GifColor col = frame.m_palette[*from++]; - if (col.a != 0) - { - *to++ = col.b; - *to++ = col.g; - *to++ = col.r; - *to++ = col.a; - } - else + unsigned char index = *from++; + + if (index >= paletteSize) { - to += 4; + CLog::Log(LOGDEBUG, "Gif::ConstructFrame(): Pixel (%d,%d) has no valid palette entry, skip it", src_x, src_y); + continue; } + + GifColor col = frame.m_palette[index]; + if (col.a != 0) + memcpy(to, &col, sizeof(GifColor)); + + to += 4; } } } @@ -447,15 +443,14 @@ bool Gif::PrepareTemplate(const GifFrame &frame) memcpy(m_pTemplate, frame.m_pImage, m_imageSize); break; - /* Set area too background color */ + /* + Clear the frame's area to transparency. + The disposal names is misleading. Do not restore to the background color because + this part of the specification is ignored by all browsers/image viewers. + */ case DISPOSE_BACKGROUND: { - if (!m_hasBackground) - { - CLog::Log(LOGDEBUG, "Gif::PrepareTemplate(): Disposal method DISPOSE_BACKGROUND encountered, but the gif has no background."); - return false; - } - SetFrameAreaToBack(m_pTemplate, frame); + ClearFrameAreaToTransparency(m_pTemplate, frame); break; } /* Restore to previous content */ @@ -488,15 +483,15 @@ bool Gif::PrepareTemplate(const GifFrame &frame) return true; } -void Gif::SetFrameAreaToBack(unsigned char* dest, const GifFrame &frame) +void Gif::ClearFrameAreaToTransparency(unsigned char* dest, const GifFrame &frame) { for (unsigned int dest_y = frame.m_top, src_y = 0; src_y < frame.m_height; ++dest_y, ++src_y) { unsigned char *to = dest + (dest_y * m_pitch) + (frame.m_left * sizeof(GifColor)); for (unsigned int src_x = 0; src_x < frame.m_width; ++src_x) { - memcpy(to, &m_backColor, sizeof(m_backColor)); - to += 4; + to += 3; + *to++ = 0; } } } diff --git a/xbmc/guilib/Gif.h b/xbmc/guilib/Gif.h index 959e076ec4..b9741503f3 100644 --- a/xbmc/guilib/Gif.h +++ b/xbmc/guilib/Gif.h @@ -92,8 +92,6 @@ private: DllLibGif m_dll; std::string m_filename; GifFileType* m_gif; - bool m_hasBackground; - GifColor m_backColor; std::vector<GifColor> m_globalPalette; unsigned char* m_pTemplate; int m_isAnimated; @@ -107,7 +105,7 @@ private: static void ConvertColorTable(std::vector<GifColor> &dest, ColorMapObject* src, unsigned int size); bool GcbToFrame(GifFrame &frame, unsigned int imgIdx); bool ExtractFrames(unsigned int count); - void SetFrameAreaToBack(unsigned char* dest, const GifFrame &frame); + void ClearFrameAreaToTransparency(unsigned char* dest, const GifFrame &frame); void ConstructFrame(GifFrame &frame, const unsigned char* src) const; bool PrepareTemplate(const GifFrame &frame); void Release(); diff --git a/xbmc/guilib/TextureManager.cpp b/xbmc/guilib/TextureManager.cpp index fd5614c76e..878cd61c52 100644 --- a/xbmc/guilib/TextureManager.cpp +++ b/xbmc/guilib/TextureManager.cpp @@ -19,25 +19,28 @@ */ #include "TextureManager.h" -#include "Texture.h" -#if defined(HAS_GIFLIB) -#include "guilib/Gif.h" -#endif//HAS_GIFLIB + +#include <cassert> + +#include "addons/Skin.h" +#include "filesystem/Directory.h" +#include "filesystem/File.h" #include "GraphicContext.h" +#include "system.h" +#include "Texture.h" #include "threads/SingleLock.h" +#include "threads/SystemClock.h" +#include "URL.h" #include "utils/log.h" -#include "utils/URIUtils.h" #include "utils/StringUtils.h" -#include "addons/Skin.h" +#include "utils/URIUtils.h" + #ifdef _DEBUG_TEXTURES #include "utils/TimeUtils.h" #endif -#include "threads/SystemClock.h" -#include "filesystem/File.h" -#include "filesystem/Directory.h" -#include "URL.h" -#include <assert.h> - +#if defined(HAS_GIFLIB) +#include "guilib/Gif.h" +#endif//HAS_GIFLIB #if defined(TARGET_DARWIN_IOS) && !defined(TARGET_DARWIN_IOS_ATV2) #include "windowing/WindowingFactory.h" // for g_Windowing in CGUITextureManager::FreeUnusedTextures #endif diff --git a/xbmc/guilib/TextureManager.h b/xbmc/guilib/TextureManager.h index 192cab2c6e..df5697c1a4 100644 --- a/xbmc/guilib/TextureManager.h +++ b/xbmc/guilib/TextureManager.h @@ -22,17 +22,15 @@ \file TextureManager.h \brief */ +#pragma once -#ifndef GUILIB_TEXTUREMANAGER_H -#define GUILIB_TEXTUREMANAGER_H - -#include <vector> #include <list> +#include <vector> +#include <utility> + #include "TextureBundle.h" #include "threads/CriticalSection.h" -#pragma once - /************************************************************************/ /* */ /************************************************************************/ @@ -141,5 +139,4 @@ protected: \ingroup textures \brief */ -extern CGUITextureManager g_TextureManager; -#endif +extern CGUITextureManager g_TextureManager;
\ No newline at end of file diff --git a/xbmc/guilib/XBTF.cpp b/xbmc/guilib/XBTF.cpp index 662a3a89fb..daeaa4d820 100644 --- a/xbmc/guilib/XBTF.cpp +++ b/xbmc/guilib/XBTF.cpp @@ -18,10 +18,11 @@ * */ -#include <cstring> - #include "XBTF.h" +#include <cstring> +#include <utility> + CXBTFFrame::CXBTFFrame() { m_width = 0; diff --git a/xbmc/input/ButtonTranslator.cpp b/xbmc/input/ButtonTranslator.cpp index ca948be2aa..6477606f96 100644 --- a/xbmc/input/ButtonTranslator.cpp +++ b/xbmc/input/ButtonTranslator.cpp @@ -18,26 +18,28 @@ * */ -#include "system.h" -#include "interfaces/builtins/Builtins.h" #include "ButtonTranslator.h" -#include "profiles/ProfilesManager.h" -#include "utils/URIUtils.h" -#include "input/Key.h" + +#include <algorithm> +#include <utility> + +#include "FileItem.h" +#include "filesystem/Directory.h" +#include "filesystem/File.h" #include "guilib/WindowIDs.h" +#include "input/Key.h" #include "input/MouseStat.h" #include "input/XBMC_keytable.h" -#include "filesystem/File.h" -#include "filesystem/Directory.h" -#include "FileItem.h" -#include "utils/StringUtils.h" +#include "interfaces/builtins/Builtins.h" +#include "profiles/ProfilesManager.h" +#include "system.h" +#include "Util.h" #include "utils/log.h" -#include "utils/XBMCTinyXML.h" #include "utils/RegExp.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include "utils/XBMCTinyXML.h" #include "XBIRRemote.h" -#include "Util.h" - -#include <algorithm> #if defined(TARGET_WINDOWS) #include "input/windows/WINJoystick.h" diff --git a/xbmc/input/InertialScrollingHandler.cpp b/xbmc/input/InertialScrollingHandler.cpp index fdb2900b7c..9356e4c00a 100644 --- a/xbmc/input/InertialScrollingHandler.cpp +++ b/xbmc/input/InertialScrollingHandler.cpp @@ -93,8 +93,16 @@ bool CInertialScrollingHandler::CheckForInertialScrolling(const CAction* action) //ask if the control wants inertial scrolling if(g_windowManager.SendMessage(message)) { - if( message.GetParam1() == EVENT_RESULT_PAN_HORIZONTAL || - message.GetParam1() == EVENT_RESULT_PAN_VERTICAL) + int result = 0; + if (message.GetPointer()) + { + int *p = static_cast<int*>(message.GetPointer()); + message.SetPointer(nullptr); + result = *p; + delete p; + } + if( result == EVENT_RESULT_PAN_HORIZONTAL || + result == EVENT_RESULT_PAN_VERTICAL) { inertialRequested = true; } diff --git a/xbmc/input/InputCodingTableBaiduPY.cpp b/xbmc/input/InputCodingTableBaiduPY.cpp index 10176e59d7..b939b94871 100644 --- a/xbmc/input/InputCodingTableBaiduPY.cpp +++ b/xbmc/input/InputCodingTableBaiduPY.cpp @@ -18,14 +18,17 @@ * */ -#include <stdlib.h> #include "InputCodingTableBaiduPY.h" + +#include <stdlib.h> +#include <utility> + #include "filesystem/CurlFile.h" #include "utils/StringUtils.h" #include "utils/RegExp.h" #include "guilib/GUIMessage.h"
#include "guilib/GUIWindowManager.h"
- +
CInputCodingTableBaiduPY::CInputCodingTableBaiduPY(const std::string& strUrl) : CThread("BaiduPYApi"),
m_messageCounter{ 0 }
diff --git a/xbmc/input/KeyboardLayoutManager.cpp b/xbmc/input/KeyboardLayoutManager.cpp index 15bca9ca8b..e2253647a8 100644 --- a/xbmc/input/KeyboardLayoutManager.cpp +++ b/xbmc/input/KeyboardLayoutManager.cpp @@ -18,12 +18,13 @@ * */ +#include "KeyboardLayoutManager.h" + #include <algorithm> -#include "KeyboardLayoutManager.h" #include "FileItem.h" -#include "URL.h" #include "filesystem/Directory.h" +#include "URL.h" #include "utils/log.h" #include "utils/XBMCTinyXML.h" diff --git a/xbmc/input/KeyboardLayoutManager.h b/xbmc/input/KeyboardLayoutManager.h index b679a51464..351eb93445 100644 --- a/xbmc/input/KeyboardLayoutManager.h +++ b/xbmc/input/KeyboardLayoutManager.h @@ -21,6 +21,7 @@ #include <map> #include <string> +#include <utility> #include "input/KeyboardLayout.h" diff --git a/xbmc/input/windows/WINJoystick.h b/xbmc/input/windows/WINJoystick.h index 693619b628..37e5f331f3 100644 --- a/xbmc/input/windows/WINJoystick.h +++ b/xbmc/input/windows/WINJoystick.h @@ -19,12 +19,14 @@ * */ -#include <vector> -#include <string> -#include <map> #include <list> +#include <map> #include <memory> +#include <string> #include <stdint.h> +#include <utility> +#include <vector> + #include "threads/CriticalSection.h" #define JACTIVE_BUTTON 0x00000001 diff --git a/xbmc/interfaces/builtins/LibraryBuiltins.cpp b/xbmc/interfaces/builtins/LibraryBuiltins.cpp index e5a21579cf..3361003975 100644 --- a/xbmc/interfaces/builtins/LibraryBuiltins.cpp +++ b/xbmc/interfaces/builtins/LibraryBuiltins.cpp @@ -106,7 +106,7 @@ static int ExportLibrary(const std::vector<std::string>& params) thumbs = StringUtils::EqualsNoCase(params[2], "true"); else { - HELPERS::DialogResponse result = HELPERS::ShowYesNoDialogText(CVariant{iHeading}, CVariant{20430}, CVariant{20428}, CVariant{20429}); + HELPERS::DialogResponse result = HELPERS::ShowYesNoDialogText(CVariant{iHeading}, CVariant{20430}); cancelled = result == HELPERS::DialogResponse::CANCELLED; thumbs = result == HELPERS::DialogResponse::YES; } @@ -147,7 +147,7 @@ static int ExportLibrary(const std::vector<std::string>& params) if (params.size() > 2) path=params[2]; - if (singleFile || !path.empty() || + if (singleFile && !path.empty() || CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(661), path, true)) { diff --git a/xbmc/interfaces/generic/ScriptInvocationManager.cpp b/xbmc/interfaces/generic/ScriptInvocationManager.cpp index 53d676ddde..4cadac57f3 100644 --- a/xbmc/interfaces/generic/ScriptInvocationManager.cpp +++ b/xbmc/interfaces/generic/ScriptInvocationManager.cpp @@ -18,10 +18,12 @@ * */ -#include <errno.h> +#include "ScriptInvocationManager.h" + +#include <cerrno> +#include <utility> #include <vector> -#include "ScriptInvocationManager.h" #include "filesystem/File.h" #include "interfaces/generic/ILanguageInvocationHandler.h" #include "interfaces/generic/ILanguageInvoker.h" diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp index 11a4d30225..6a60a794f0 100644 --- a/xbmc/interfaces/json-rpc/PVROperations.cpp +++ b/xbmc/interfaces/json-rpc/PVROperations.cpp @@ -182,7 +182,7 @@ JSONRPC_STATUS CPVROperations::GetBroadcastDetails(const std::string &method, IT EpgSearchFilter filter; filter.Reset(); - filter.m_iUniqueBroadcastId = (int)parameterObject["broadcastid"].asInteger(); + filter.m_iUniqueBroadcastId = parameterObject["broadcastid"].asUnsignedInteger(); CFileItemList broadcasts; int resultSize = g_EpgContainer.GetEPGSearch(broadcasts, filter); diff --git a/xbmc/interfaces/json-rpc/schema/types.json b/xbmc/interfaces/json-rpc/schema/types.json index bd6c1d6c0b..08fe9ee36f 100644 --- a/xbmc/interfaces/json-rpc/schema/types.json +++ b/xbmc/interfaces/json-rpc/schema/types.json @@ -519,7 +519,7 @@ "Video.Fields.MovieSet": { "extends": "Item.Fields.Base", "items": { "type": "string", - "enum": [ "title", "playcount", "fanart", "thumbnail", "art" ] + "enum": [ "title", "playcount", "fanart", "thumbnail", "art", "plot" ] } }, "Video.Fields.TVShow": { @@ -680,7 +680,8 @@ "Video.Details.MovieSet": { "extends": "Video.Details.Media", "properties": { - "setid": { "$ref": "Library.Id", "required": true } + "setid": { "$ref": "Library.Id", "required": true }, + "plot": { "type": "string" } } }, "Video.Details.MovieSet.Extended": { diff --git a/xbmc/interfaces/json-rpc/schema/version.txt b/xbmc/interfaces/json-rpc/schema/version.txt index 8993da9773..94ae9e992e 100644 --- a/xbmc/interfaces/json-rpc/schema/version.txt +++ b/xbmc/interfaces/json-rpc/schema/version.txt @@ -1 +1 @@ -6.28.1 +6.29.0 diff --git a/xbmc/interfaces/legacy/Window.cpp b/xbmc/interfaces/legacy/Window.cpp index 3c0d5c273b..100b8c4b8b 100644 --- a/xbmc/interfaces/legacy/Window.cpp +++ b/xbmc/interfaces/legacy/Window.cpp @@ -455,20 +455,6 @@ namespace XBMCAddon XBMC_TRACE; switch (message.GetMessage()) { - case GUI_MSG_WINDOW_DEINIT: - { - g_windowManager.ShowOverlay(ref(window)->OVERLAY_STATE_SHOWN); - } - break; - - case GUI_MSG_WINDOW_INIT: - { - ref(window)->OnMessage(message); - g_windowManager.ShowOverlay(ref(window)->OVERLAY_STATE_HIDDEN); - return true; - } - break; - case GUI_MSG_CLICKED: { int iControl=message.GetSenderId(); diff --git a/xbmc/interfaces/legacy/WindowXML.cpp b/xbmc/interfaces/legacy/WindowXML.cpp index c6c8edd586..ef9bb8d62a 100644 --- a/xbmc/interfaces/legacy/WindowXML.cpp +++ b/xbmc/interfaces/legacy/WindowXML.cpp @@ -473,12 +473,8 @@ namespace XBMCAddon { XBMC_TRACE; if (message.GetMessage() == GUI_MSG_WINDOW_DEINIT) - { - CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow()); - if (pWindow) - g_windowManager.ShowOverlay(pWindow->GetOverlayState()); return A(CGUIWindow::OnMessage(message)); - } + return WindowXML::OnMessage(message); } diff --git a/xbmc/interfaces/legacy/wsgi/WsgiResponse.cpp b/xbmc/interfaces/legacy/wsgi/WsgiResponse.cpp index 7761adeed6..e9af10d5f8 100644 --- a/xbmc/interfaces/legacy/wsgi/WsgiResponse.cpp +++ b/xbmc/interfaces/legacy/wsgi/WsgiResponse.cpp @@ -19,9 +19,13 @@ */ #include "WsgiResponse.h" + +#include <utility> + #include "utils/log.h" #include "utils/StringUtils.h" + namespace XBMCAddon { namespace xbmcwsgi diff --git a/xbmc/interfaces/python/AddonPythonInvoker.cpp b/xbmc/interfaces/python/AddonPythonInvoker.cpp index 0fdc525676..c5b1731421 100644 --- a/xbmc/interfaces/python/AddonPythonInvoker.cpp +++ b/xbmc/interfaces/python/AddonPythonInvoker.cpp @@ -29,6 +29,8 @@ #include "system.h" #include "AddonPythonInvoker.h" +#include <utility> + #define MODULE "xbmc" #define RUNSCRIPT_PRAMBLE \ diff --git a/xbmc/interfaces/python/swig.cpp b/xbmc/interfaces/python/swig.cpp index d8d5ad9a94..fea0a23d9a 100644 --- a/xbmc/interfaces/python/swig.cpp +++ b/xbmc/interfaces/python/swig.cpp @@ -196,16 +196,16 @@ namespace PythonBindings PyObject *tracebackModule = PyImport_ImportModule("traceback"); if (tracebackModule != NULL) { - char format_exception[] = "format_exception"; - char zeros[] = "000"; - PyObject *tbList = PyObject_CallMethod(tracebackModule, format_exception, zeros, exc_type, exc_value == NULL ? Py_None : exc_value, exc_traceback == NULL ? Py_None : exc_traceback); + char method[] = "format_exception"; + char format[] = "OOO"; + PyObject *tbList = PyObject_CallMethod(tracebackModule, method, format, exc_type, exc_value == NULL ? Py_None : exc_value, exc_traceback == NULL ? Py_None : exc_traceback); if (tbList) { PyObject *emptyString = PyString_FromString(""); - char join[] = "join"; - char zero[] = "O"; - PyObject *strRetval = PyObject_CallMethod(emptyString, join, zero, tbList); + char method[] = "join"; + char format[] = "O"; + PyObject *strRetval = PyObject_CallMethod(emptyString, method, format, tbList); Py_DECREF(emptyString); if (strRetval) diff --git a/xbmc/linux/XTimeUtils.cpp b/xbmc/linux/XTimeUtils.cpp index 1d4d99a5e0..bcdc5ce79f 100644 --- a/xbmc/linux/XTimeUtils.cpp +++ b/xbmc/linux/XTimeUtils.cpp @@ -88,7 +88,7 @@ BOOL FileTimeToLocalFileTime(const FILETIME* lpFileTime, LPFILETIME lpLocalFileT FileTimeToTimeT(lpFileTime, &ft); localtime_r(&ft, &tm_ft); - l.QuadPart += tm_ft.tm_gmtoff * 10000000; + l.QuadPart += (ULONGLONG)tm_ft.tm_gmtoff * 10000000; lpLocalFileTime->dwLowDateTime = l.u.LowPart; lpLocalFileTime->dwHighDateTime = l.u.HighPart; diff --git a/xbmc/listproviders/DirectoryProvider.cpp b/xbmc/listproviders/DirectoryProvider.cpp index 223ca29c99..106037c62c 100644 --- a/xbmc/listproviders/DirectoryProvider.cpp +++ b/xbmc/listproviders/DirectoryProvider.cpp @@ -19,24 +19,26 @@ */ #include "DirectoryProvider.h" + +#include <memory> +#include <utility> + +#include "FileItem.h" #include "filesystem/Directory.h" #include "filesystem/FavouritesDirectory.h" #include "guilib/GUIWindowManager.h" +#include "interfaces/AnnouncementManager.h" +#include "messaging/ApplicationMessenger.h" +#include "music/MusicThumbLoader.h" +#include "pictures/PictureThumbLoader.h" #include "settings/Settings.h" +#include "threads/SingleLock.h" #include "utils/JobManager.h" #include "utils/SortUtils.h" -#include "utils/XMLUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" -#include "threads/SingleLock.h" -#include "messaging/ApplicationMessenger.h" -#include "FileItem.h" +#include "utils/XMLUtils.h" #include "video/VideoThumbLoader.h" -#include "music/MusicThumbLoader.h" -#include "pictures/PictureThumbLoader.h" -#include "interfaces/AnnouncementManager.h" - -#include <memory> using namespace XFILE; using namespace ANNOUNCEMENT; diff --git a/xbmc/media/MediaType.cpp b/xbmc/media/MediaType.cpp index 2b30cb58e9..ed0d9523b5 100644 --- a/xbmc/media/MediaType.cpp +++ b/xbmc/media/MediaType.cpp @@ -19,9 +19,13 @@ */ #include "MediaType.h" + +#include <utility> + #include "guilib/LocalizeStrings.h" #include "utils/StringUtils.h" + static std::map<std::string, MediaTypes::MediaTypeInfo> fillDefaultMediaTypes() { std::map<std::string, MediaTypes::MediaTypeInfo> mediaTypes; diff --git a/xbmc/messaging/ApplicationMessenger.cpp b/xbmc/messaging/ApplicationMessenger.cpp index e6327b2afc..1880693594 100644 --- a/xbmc/messaging/ApplicationMessenger.cpp +++ b/xbmc/messaging/ApplicationMessenger.cpp @@ -19,12 +19,13 @@ */ #include "ApplicationMessenger.h" -#include "Application.h" - -#include "threads/SingleLock.h" -#include "guilib/GraphicContext.h" #include <memory> +#include <utility> + +#include "Application.h" +#include "guilib/GraphicContext.h" +#include "threads/SingleLock.h" namespace KODI { diff --git a/xbmc/music/Artist.h b/xbmc/music/Artist.h index 6e08d68be7..834033d95b 100644 --- a/xbmc/music/Artist.h +++ b/xbmc/music/Artist.h @@ -22,11 +22,12 @@ #include <map> #include <string> +#include <utility> #include <vector> -#include "XBDateTime.h" -#include "utils/ScraperUrl.h" #include "utils/Fanart.h" +#include "utils/ScraperUrl.h" +#include "XBDateTime.h" class TiXmlNode; class CAlbum; diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp index 4e2d9b505c..91be41e093 100644 --- a/xbmc/music/MusicDatabase.cpp +++ b/xbmc/music/MusicDatabase.cpp @@ -18,59 +18,59 @@ * */ -#include "network/Network.h" -#include "threads/SystemClock.h" -#include "system.h" #include "MusicDatabase.h" -#include "network/cddb.h" -#include "filesystem/DirectoryCache.h" -#include "filesystem/MusicDatabaseDirectory/DirectoryNode.h" -#include "filesystem/MusicDatabaseDirectory/QueryParams.h" -#include "GUIInfoManager.h" -#include "music/tags/MusicInfoTag.h" + +#include "addons/Addon.h" #include "addons/AddonManager.h" #include "addons/Scraper.h" -#include "addons/Addon.h" -#include "utils/URIUtils.h" -#include "Artist.h" #include "Album.h" -#include "Song.h" -#include "guilib/GUIWindowManager.h" +#include "Application.h" +#include "Artist.h" +#include "CueInfoLoader.h" +#include "dbwrappers/dataset.h" +#include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogOK.h" #include "dialogs/GUIDialogProgress.h" -#include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogSelect.h" +#include "FileItem.h" +#include "filesystem/DirectoryCache.h" #include "filesystem/File.h" +#include "filesystem/MusicDatabaseDirectory/DirectoryNode.h" +#include "filesystem/MusicDatabaseDirectory/QueryParams.h" +#include "guiinfo/GUIInfoLabels.h" +#include "GUIInfoManager.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "interfaces/AnnouncementManager.h" +#include "messaging/helpers/DialogHelper.h" +#include "music/tags/MusicInfoTag.h" +#include "network/cddb.h" +#include "network/Network.h" +#include "playlists/SmartPlayList.h" #include "profiles/ProfilesManager.h" #include "settings/AdvancedSettings.h" -#include "FileItem.h" -#include "Application.h" -#ifdef HAS_KARAOKE -#include "karaoke/karaokelyricsfactory.h" -#endif -#include "storage/MediaManager.h" #include "settings/MediaSettings.h" #include "settings/Settings.h" -#include "utils/StringUtils.h" -#include "utils/Variant.h" -#include "guilib/LocalizeStrings.h" +#include "Song.h" +#include "storage/MediaManager.h" +#include "system.h" +#include "TextureCache.h" +#include "threads/SystemClock.h" +#include "URL.h" #include "utils/FileUtils.h" #include "utils/LegacyPathTranslation.h" #include "utils/log.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" #include "TextureCache.h" -#include "utils/AutoPtrHandle.h" #include "interfaces/AnnouncementManager.h" #include "dbwrappers/dataset.h" #include "utils/XMLUtils.h" -#include "URL.h" -#include "playlists/SmartPlayList.h" -#include "CueInfoLoader.h" -#include "guiinfo/GUIInfoLabels.h" -#include "messaging/helpers/DialogHelper.h" -#include <utility> +#ifdef HAS_KARAOKE +#include "karaoke/karaokelyricsfactory.h" +#endif -using namespace AUTOPTR; using namespace XFILE; using namespace MUSICDATABASEDIRECTORY; using namespace KODI::MESSAGING; @@ -409,7 +409,7 @@ void CMusicDatabase::SaveCuesheet(const std::string& fullSongPath, const std::st return; strSQL = PrepareSQL("SELECT * FROM cue WHERE idPath=%i AND strFileName='%s'", idPath, strFileName.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) { if (strCuesheet.empty()) @@ -434,7 +434,7 @@ void CMusicDatabase::SaveCuesheet(const std::string& fullSongPath, const std::st } } m_pDS->close(); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); m_cueCache.insert(CueCache::value_type(fullSongPath, strCuesheet)); } catch (...) @@ -469,7 +469,7 @@ std::string CMusicDatabase::LoadCuesheet(const std::string& fullSongPath) return strCuesheet; strSQL = PrepareSQL("select strCuesheet from cue where idPath=%i AND strFileName='%s'", idPath, strFileName.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (0 < m_pDS->num_rows()) strCuesheet = m_pDS->get_sql_record()->at(0).get_asString(); @@ -662,7 +662,7 @@ int CMusicDatabase::AddSong(const int idAlbum, strTitle.c_str(), iTrack); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return -1; if (m_pDS->num_rows() == 0) @@ -688,7 +688,7 @@ int CMusicDatabase::AddSong(const int idAlbum, else strSQL += PrepareSQL(",%i,%i,%i,NULL,'%c','%s', '%s')", iTimesPlayed, iStartOffset, iEndOffset, rating, strComment.c_str(), strMood.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); idSong = (int)m_pDS->lastinsertid(); } else @@ -746,7 +746,7 @@ bool CMusicDatabase::GetSong(int idSong, CSong& song) " LEFT JOIN songartistview ON songview.idSong = songartistview.idSong " " WHERE songview.idSong = %i", idSong); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -867,7 +867,7 @@ int CMusicDatabase::AddAlbum(const std::string& strAlbum, const std::string& str strSQL = PrepareSQL("SELECT * FROM album WHERE strArtists LIKE '%s' AND strAlbum LIKE '%s' AND strMusicBrainzAlbumID IS NULL", strArtist.c_str(), strAlbum.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) { @@ -890,7 +890,7 @@ int CMusicDatabase::AddAlbum(const std::string& strAlbum, const std::string& str year, bCompilation, CAlbum::ReleaseTypeToString(releaseType).c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return (int)m_pDS->lastinsertid(); } @@ -923,7 +923,7 @@ int CMusicDatabase::AddAlbum(const std::string& strAlbum, const std::string& str bCompilation, CAlbum::ReleaseTypeToString(releaseType).c_str(), idAlbum); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); DeleteAlbumArtistsByAlbum(idAlbum); DeleteAlbumGenresByAlbum(idAlbum); return idAlbum; @@ -1010,7 +1010,7 @@ bool CMusicDatabase::GetAlbum(int idAlbum, CAlbum& album, bool getSongs /* = tru } CLog::Log(LOGDEBUG, "%s", sql.c_str()); - if (!m_pDS->query(sql.c_str())) return false; + if (!m_pDS->query(sql)) return false; if (m_pDS->num_rows() == 0) { m_pDS->close(); @@ -1115,13 +1115,13 @@ int CMusicDatabase::AddGenre(const std::string& strGenre1) strSQL=PrepareSQL("select * from genre where strGenre like '%s'", strGenre.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) { m_pDS->close(); // doesnt exists, add it strSQL=PrepareSQL("insert into genre (idGenre, strGenre) values( NULL, '%s' )", strGenre.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); int idGenre = (int)m_pDS->lastinsertid(); m_genreCache.insert(std::pair<std::string, int>(strGenre1, idGenre)); @@ -1182,7 +1182,7 @@ int CMusicDatabase::AddArtist(const std::string& strArtist, const std::string& s // 1.a) Match on a MusicBrainz ID strSQL = PrepareSQL("SELECT * FROM artist WHERE strMusicBrainzArtistID = '%s'", strMusicBrainzArtistID.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() > 0) { int idArtist = (int)m_pDS->fv("idArtist").get_asInt(); @@ -1191,7 +1191,7 @@ int CMusicDatabase::AddArtist(const std::string& strArtist, const std::string& s if (update) { strSQL = PrepareSQL( "UPDATE artist SET strArtist = '%s' WHERE idArtist = %i", strArtist.c_str(), idArtist); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); m_pDS->close(); } return idArtist; @@ -1202,7 +1202,7 @@ int CMusicDatabase::AddArtist(const std::string& strArtist, const std::string& s // 1.b) No match on MusicBrainz ID. Look for a previously added artist with no MusicBrainz ID // and update that if it exists. strSQL = PrepareSQL("SELECT * FROM artist WHERE strArtist LIKE '%s' AND strMusicBrainzArtistID IS NULL", strArtist.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() > 0) { int idArtist = (int)m_pDS->fv("idArtist").get_asInt(); @@ -1212,7 +1212,7 @@ int CMusicDatabase::AddArtist(const std::string& strArtist, const std::string& s strArtist.c_str(), strMusicBrainzArtistID.c_str(), idArtist); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return idArtist; } @@ -1225,7 +1225,7 @@ int CMusicDatabase::AddArtist(const std::string& strArtist, const std::string& s strSQL = PrepareSQL("SELECT * FROM artist WHERE strArtist LIKE '%s'", strArtist.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() > 0) { int idArtist = (int)m_pDS->fv("idArtist").get_asInt(); @@ -1244,7 +1244,7 @@ int CMusicDatabase::AddArtist(const std::string& strArtist, const std::string& s strArtist.c_str(), strMusicBrainzArtistID.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); int idArtist = (int)m_pDS->lastinsertid(); return idArtist; } @@ -1313,7 +1313,7 @@ bool CMusicDatabase::GetArtist(int idArtist, CArtist &artist, bool fetchAll /* = else strSQL = PrepareSQL("SELECT * FROM artistview WHERE artistview.idArtist = %i", idArtist); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { m_pDS->close(); @@ -1441,7 +1441,7 @@ bool CMusicDatabase::GetAlbumsByArtist(int idArtist, bool includeFeatured, std:: strPrepSQL += " AND boolFeatured = 0"; strSQL=PrepareSQL(strPrepSQL, idArtist); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { @@ -1475,7 +1475,7 @@ bool CMusicDatabase::GetArtistsByAlbum(int idAlbum, bool includeFeatured, std::v strPrepSQL += " AND boolFeatured = 0"; strSQL=PrepareSQL(strPrepSQL, idAlbum); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { @@ -1509,7 +1509,7 @@ bool CMusicDatabase::GetSongsByArtist(int idArtist, bool includeFeatured, std::v strPrepSQL += " AND boolFeatured = 0"; strSQL=PrepareSQL(strPrepSQL, idArtist); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { @@ -1543,7 +1543,7 @@ bool CMusicDatabase::GetArtistsBySong(int idSong, bool includeFeatured, std::vec strPrepSQL += " AND boolFeatured = 0"; strSQL=PrepareSQL(strPrepSQL, idSong); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { @@ -1571,7 +1571,7 @@ bool CMusicDatabase::GetGenresByAlbum(int idAlbum, std::vector<int>& genres) try { std::string strSQL = PrepareSQL("select idGenre from album_genre where idAlbum = %i ORDER BY iOrder ASC", idAlbum); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { @@ -1600,7 +1600,7 @@ bool CMusicDatabase::GetGenresBySong(int idSong, std::vector<int>& genres) try { std::string strSQL = PrepareSQL("select idGenre from song_genre where idSong = %i ORDER BY iOrder ASC", idSong); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { @@ -1643,13 +1643,13 @@ int CMusicDatabase::AddPath(const std::string& strPath1) return it->second; strSQL=PrepareSQL( "select * from path where strPath='%s'", strPath.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) { m_pDS->close(); // doesnt exists, add it strSQL=PrepareSQL("insert into path (idPath, strPath) values( NULL, '%s' )", strPath.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); int idPath = (int)m_pDS->lastinsertid(); m_pathCache.insert(std::pair<std::string, int>(strPath, idPath)); @@ -1890,7 +1890,7 @@ int CMusicDatabase::GetAlbumIdByPath(const std::string& strPath) try { std::string strSQL=PrepareSQL("select distinct idAlbum from song join path on song.idPath = path.idPath where path.strPath='%s'", strPath.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->eof()) return -1; @@ -1915,7 +1915,7 @@ int CMusicDatabase::GetSongByArtistAndAlbumAndTitle(const std::string& strArtist "where strArtists like '%s' and strAlbum like '%s' and " "strTitle like '%s'",strArtist.c_str(),strAlbum.c_str(),strTitle.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -1952,7 +1952,7 @@ bool CMusicDatabase::SearchArtists(const std::string& search, CFileItemList &art "where strArtist like '%s%%' and strArtist <> '%s' " , search.c_str(), strVariousArtists.c_str() ); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { m_pDS->close(); @@ -2001,7 +2001,7 @@ bool CMusicDatabase::GetTop100(const std::string& strBaseDir, CFileItemList& ite "limit 100"; CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2044,7 +2044,7 @@ bool CMusicDatabase::GetTop100Albums(VECALBUMS& albums) "limit 100 "; CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2079,9 +2079,9 @@ bool CMusicDatabase::GetTop100AlbumSongs(const std::string& strBaseDir, CFileIte if (!strBaseDir.empty() && baseUrl.FromString(strBaseDir)) return false; - std::string strSQL = StringUtils::Format("select * from songview join albumview on (songview.idAlbum = albumview.idAlbum) where albumview.idAlbum in (select song.idAlbum from song where song.iTimesPlayed>0 group by idAlbum order by sum(song.iTimesPlayed) desc limit 100) order by albumview.idAlbum in (select song.idAlbum from song where song.iTimesPlayed>0 group by idAlbum order by sum(song.iTimesPlayed) desc limit 100)"); + std::string strSQL = StringUtils::Format("SELECT songview.*, albumview.* FROM songview JOIN albumview ON (songview.idAlbum = albumview.idAlbum) JOIN (SELECT song.idAlbum, SUM(song.iTimesPlayed) AS iTimesPlayedSum FROM song WHERE song.iTimesPlayed > 0 GROUP BY idAlbum ORDER BY iTimesPlayedSum DESC LIMIT 100) AS _albumlimit ON (songview.idAlbum = _albumlimit.idAlbum) ORDER BY _albumlimit.iTimesPlayedSum DESC"); CLog::Log(LOGDEBUG,"GetTop100AlbumSongs() query: %s", strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) @@ -2121,7 +2121,7 @@ bool CMusicDatabase::GetRecentlyPlayedAlbums(VECALBUMS& albums) std::string strSQL = StringUtils::Format("select distinct albumview.* from song join albumview on albumview.idAlbum=song.idAlbum where song.lastplayed IS NOT NULL order by song.lastplayed desc limit %i", RECENTLY_PLAYED_LIMIT); CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2156,9 +2156,9 @@ bool CMusicDatabase::GetRecentlyPlayedAlbumSongs(const std::string& strBaseDir, if (!strBaseDir.empty() && !baseUrl.FromString(strBaseDir)) return false; - std::string strSQL = StringUtils::Format("select * from songview join albumview on (songview.idAlbum = albumview.idAlbum) where albumview.idAlbum in (select distinct albumview.idAlbum from albumview join song on albumview.idAlbum=song.idAlbum where song.lastplayed IS NOT NULL order by song.lastplayed desc limit %i)", g_advancedSettings.m_iMusicLibraryRecentlyAddedItems); + std::string strSQL = StringUtils::Format("SELECT songview.*, albumview.* FROM songview JOIN albumview ON (songview.idAlbum = albumview.idAlbum) JOIN (SELECT DISTINCT album.idAlbum FROM album JOIN song ON album.idAlbum = song.idAlbum WHERE song.lastplayed IS NOT NULL ORDER BY song.lastplayed DESC LIMIT %i) AS _albumlimit ON (albumview.idAlbum = _albumlimit.idAlbum)", g_advancedSettings.m_iMusicLibraryRecentlyAddedItems); CLog::Log(LOGDEBUG,"GetRecentlyPlayedAlbumSongs() query: %s", strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) @@ -2199,7 +2199,7 @@ bool CMusicDatabase::GetRecentlyAddedAlbums(VECALBUMS& albums, unsigned int limi std::string strSQL = StringUtils::Format("select * from albumview where strAlbum != '' order by idAlbum desc limit %u", limit ? limit : g_advancedSettings.m_iMusicLibraryRecentlyAddedItems); CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2238,7 +2238,7 @@ bool CMusicDatabase::GetRecentlyAddedAlbumSongs(const std::string& strBaseDir, C std::string strSQL; strSQL = PrepareSQL("SELECT songview.* FROM (SELECT idAlbum FROM albumview ORDER BY idAlbum DESC LIMIT %u) AS recentalbums JOIN songview ON songview.idAlbum=recentalbums.idAlbum", limit ? limit : g_advancedSettings.m_iMusicLibraryRecentlyAddedItems); CLog::Log(LOGDEBUG,"GetRecentlyAddedAlbumSongs() query: %s", strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) @@ -2278,7 +2278,7 @@ void CMusicDatabase::IncrementPlayCount(const CFileItem& item) int idSong = GetSongIDFromPath(item.GetPath()); std::string sql=PrepareSQL("UPDATE song SET iTimesPlayed=iTimesPlayed+1, lastplayed=CURRENT_TIMESTAMP where idSong=%i", idSong); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } catch (...) { @@ -2301,7 +2301,7 @@ bool CMusicDatabase::GetSongsByPath(const std::string& strPath1, MAPSONGS& songs if (NULL == m_pDS.get()) return false; std::string strSQL=PrepareSQL("select * from songview where strPath='%s'", strPath.c_str() ); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2372,7 +2372,7 @@ bool CMusicDatabase::SearchSongs(const std::string& search, CFileItemList &items else strSQL=PrepareSQL("select * from songview where strTitle like '%s%%' limit 1000", search.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) return false; std::string songLabel = g_localizeStrings.Get(179); // Song @@ -2408,7 +2408,7 @@ bool CMusicDatabase::SearchAlbums(const std::string& search, CFileItemList &albu else strSQL=PrepareSQL("select * from albumview where strAlbum like '%s%%'", search.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; std::string albumLabel(g_localizeStrings.Get(558)); // Album while (!m_pDS->eof()) @@ -2441,7 +2441,7 @@ bool CMusicDatabase::CleanupSongsByIds(const std::string &strSongIds) if (NULL == m_pDS.get()) return false; // ok, now find all idSong's std::string strSQL=PrepareSQL("select * from song join path on song.idPath = path.idPath where song.idSong in %s", strSongIds.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2476,7 +2476,7 @@ bool CMusicDatabase::CleanupSongsByIds(const std::string &strSongIds) std::string strSongsToDelete = "(" + StringUtils::Join(songsToDelete, ",") + ")"; // ok, now delete these songs + all references to them from the linked tables strSQL = "delete from song where idSong in " + strSongsToDelete; - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); m_pDS->close(); } return true; @@ -2497,7 +2497,7 @@ bool CMusicDatabase::CleanupSongs() for (int i=0;;i+=iLIMIT) { std::string strSQL=PrepareSQL("select song.idSong from song order by song.idSong limit %i offset %i",iLIMIT,i); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); // keep going until no rows are left! if (iRowsFound == 0) @@ -2533,7 +2533,7 @@ bool CMusicDatabase::CleanupAlbums() // This must be run AFTER songs have been cleaned up // delete albums with no reference to songs std::string strSQL = "select * from album where album.idAlbum not in (select idAlbum from song)"; - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2552,7 +2552,7 @@ bool CMusicDatabase::CleanupAlbums() std::string strAlbumIds = "(" + StringUtils::Join(albumIds, ",") + ")"; // ok, now we can delete them and the references in the linked tables strSQL = "delete from album where idAlbum in " + strAlbumIds; - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } catch (...) @@ -2576,7 +2576,7 @@ bool CMusicDatabase::CleanupPaths() // grab all paths that aren't immediately connected with a song std::string sql = "select * from path where idPath not in (select idPath from song)"; - if (!m_pDS->query(sql.c_str())) return false; + if (!m_pDS->query(sql)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -2590,7 +2590,7 @@ bool CMusicDatabase::CleanupPaths() // anything that isn't a parent path of a song path is to be deleted std::string path = m_pDS->fv("strPath").get_asString(); std::string sql = PrepareSQL("select count(idPath) from songpaths where SUBSTR(strPath,1,%i)='%s'", StringUtils::utf8_strlen(path.c_str()), path.c_str()); - if (m_pDS2->query(sql.c_str()) && m_pDS2->num_rows() == 1 && m_pDS2->fv(0).get_asInt() == 0) + if (m_pDS2->query(sql) && m_pDS2->num_rows() == 1 && m_pDS2->fv(0).get_asInt() == 0) pathIds.push_back(m_pDS->fv("idPath").get_asString()); // nothing found, so delete m_pDS2->close(); m_pDS->next(); @@ -2601,7 +2601,7 @@ bool CMusicDatabase::CleanupPaths() { // do the deletion, and drop our temp table std::string deleteSQL = "DELETE FROM path WHERE idPath IN (" + StringUtils::Join(pathIds, ",") + ")"; - m_pDS->exec(deleteSQL.c_str()); + m_pDS->exec(deleteSQL); } m_pDS->exec("drop table songpaths"); return true; @@ -2651,7 +2651,7 @@ bool CMusicDatabase::CleanupGenres() // Must be executed AFTER the song, song_genre, album and album_genre tables have been cleaned. std::string strSQL = "delete from genre where idGenre not in (select idGenre from song_genre) and"; strSQL += " idGenre not in (select idGenre from album_genre)"; - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } catch (...) @@ -3114,7 +3114,7 @@ bool CMusicDatabase::GetYearsNav(const std::string& strBaseDir, CFileItemList& i // run query CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) @@ -3197,7 +3197,7 @@ bool CMusicDatabase::GetCommonNav(const std::string &strBaseDir, const std::stri // run query CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); @@ -3353,7 +3353,7 @@ bool CMusicDatabase::GetArtistsByWhere(const std::string& strBaseDir, const Filt // run query CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound == 0) { @@ -3433,7 +3433,7 @@ bool CMusicDatabase::GetAlbumFromSong(int idSong, CAlbum &album) if (NULL == m_pDS.get()) return false; std::string strSQL = PrepareSQL("select albumview.* from song join albumview on song.idAlbum = albumview.idAlbum where song.idSong='%i'", idSong); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound != 1) { @@ -3513,7 +3513,7 @@ bool CMusicDatabase::GetAlbumsByWhere(const std::string &baseDir, const Filter & CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); // run query unsigned int time = XbmcThreads::SystemClockMillis(); - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; CLog::Log(LOGDEBUG, "%s - query took %i ms", __FUNCTION__, XbmcThreads::SystemClockMillis() - time); time = XbmcThreads::SystemClockMillis(); @@ -3625,7 +3625,7 @@ bool CMusicDatabase::GetSongsByWhere(const std::string &baseDir, const Filter &f CLog::Log(LOGDEBUG, "%s query = %s", __FUNCTION__, strSQL.c_str()); // run query - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); @@ -3762,7 +3762,7 @@ void CMusicDatabase::UpdateTables(int version) { std::string originalPath = *it; std::string path = CLegacyPathTranslation::TranslateMusicDbPath(originalPath); - m_pDS->exec(PrepareSQL("UPDATE content SET strPath='%s' WHERE strPath='%s'", path.c_str(), originalPath.c_str()).c_str()); + m_pDS->exec(PrepareSQL("UPDATE content SET strPath='%s' WHERE strPath='%s'", path.c_str(), originalPath.c_str())); } } } @@ -3843,7 +3843,7 @@ void CMusicDatabase::UpdateTables(int version) m_pDS->exec("ALTER TABLE song_artist ADD strArtist text\n"); // populate these std::string sql = "select idArtist,strArtist from artist"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); while (!m_pDS->eof()) { m_pDS2->exec(PrepareSQL("UPDATE song_artist SET strArtist='%s' where idArtist=%i", m_pDS->fv(1).get_asString().c_str(), m_pDS->fv(0).get_asInt())); @@ -3964,7 +3964,7 @@ unsigned int CMusicDatabase::GetSongIDs(const Filter &filter, std::vector<std::p if (!CDatabase::BuildSQL(strSQL, filter, strSQL)) return false; - if (!m_pDS->query(strSQL.c_str())) return 0; + if (!m_pDS->query(strSQL)) return 0; songIDs.clear(); if (m_pDS->num_rows() == 0) { @@ -3998,7 +3998,7 @@ int CMusicDatabase::GetSongsCount(const Filter &filter) if (!CDatabase::BuildSQL(strSQL, filter, strSQL)) return false; - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { m_pDS->close(); @@ -4027,7 +4027,7 @@ bool CMusicDatabase::GetAlbumPath(int idAlbum, std::string& path) path.clear(); std::string strSQL=PrepareSQL("select strPath from song join path on song.idPath = path.idPath where song.idAlbum=%ld", idAlbum); - if (!m_pDS2->query(strSQL.c_str())) return false; + if (!m_pDS2->query(strSQL)) return false; int iRowsFound = m_pDS2->num_rows(); if (iRowsFound == 0) { @@ -4082,7 +4082,7 @@ bool CMusicDatabase::GetArtistPath(int idArtist, std::string &basePath) " GROUP BY song.idPath", idArtist); // run query - if (!m_pDS2->query(strSQL.c_str())) return false; + if (!m_pDS2->query(strSQL)) return false; int iRowsFound = m_pDS2->num_rows(); if (iRowsFound == 0) { @@ -4133,7 +4133,7 @@ int CMusicDatabase::GetArtistByName(const std::string& strArtist) std::string strSQL=PrepareSQL("select idArtist from artist where artist.strArtist like '%s'", strArtist.c_str()); // run query - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound != 1) { @@ -4164,7 +4164,7 @@ int CMusicDatabase::GetAlbumByName(const std::string& strAlbum, const std::strin else strSQL=PrepareSQL("SELECT album.idAlbum FROM album WHERE album.strAlbum LIKE '%s' AND album.strArtists LIKE '%s'", strAlbum.c_str(),strArtist.c_str()); // run query - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound != 1) { @@ -4210,7 +4210,7 @@ int CMusicDatabase::GetGenreByName(const std::string& strGenre) std::string strSQL; strSQL=PrepareSQL("select idGenre from genre where genre.strGenre like '%s'", strGenre.c_str()); // run query - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound != 1) { @@ -4246,7 +4246,7 @@ bool CMusicDatabase::GetRandomSong(CFileItem* item, int& idSong, const Filter &f CLog::Log(LOGDEBUG, "%s query = %s", __FUNCTION__, strSQL.c_str()); // run query - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound != 1) @@ -4318,7 +4318,7 @@ bool CMusicDatabase::SetPathHash(const std::string &path, const std::string &has if (idPath < 0) return false; std::string strSQL=PrepareSQL("update path set strHash='%s' where idPath=%ld", hash.c_str(), idPath); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } @@ -4338,7 +4338,7 @@ bool CMusicDatabase::GetPathHash(const std::string &path, std::string &hash) if (NULL == m_pDS.get()) return false; std::string strSQL=PrepareSQL("select strHash from path where strPath='%s'", path.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) return false; hash = m_pDS->fv("strHash").get_asString(); @@ -4395,7 +4395,7 @@ bool CMusicDatabase::RemoveSongsFromPath(const std::string &path1, MAPSONGS& son else where = PrepareSQL(" where SUBSTR(strPath,1,%i)='%s'", StringUtils::utf8_strlen(path.c_str()), path.c_str()); std::string sql = "select * from songview" + where; - if (!m_pDS->query(sql.c_str())) return false; + if (!m_pDS->query(sql)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound > 0) { @@ -4416,11 +4416,11 @@ bool CMusicDatabase::RemoveSongsFromPath(const std::string &path1, MAPSONGS& son // and delete all songs, and anything linked to them sql = "delete from song where idSong in (" + StringUtils::Join(songIds, ",") + ")"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } // and remove the path as well (it'll be re-added later on with the new hash if it's non-empty) sql = "delete from path" + where; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); return iRowsFound > 0; } catch (...) @@ -4474,7 +4474,7 @@ bool CMusicDatabase::SetSongRating(const std::string &filePath, char rating) if (-1 == songID) return false; std::string sql = PrepareSQL("update song set rating='%c' where idSong = %i", rating, songID); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); return true; } catch (...) @@ -4505,7 +4505,7 @@ int CMusicDatabase::GetSongIDFromPath(const std::string &filePath) URIUtils::AddSlashAtEnd(strPath); std::string sql = PrepareSQL("select idSong from song join path on song.idPath = path.idPath where song.strFileName='%s' and path.strPath='%s'", strFileName.c_str(), strPath.c_str()); - if (!m_pDS->query(sql.c_str())) return -1; + if (!m_pDS->query(sql)) return -1; if (m_pDS->num_rows() == 0) { @@ -4543,12 +4543,12 @@ bool CMusicDatabase::SetScraperForPath(const std::string& strPath, const ADDON:: // wipe old settings std::string strSQL = PrepareSQL("delete from content where strPath='%s'",strPath.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); // insert new settings strSQL = PrepareSQL("insert into content (strPath, strScraperPath, strContent, strSettings) values ('%s','%s','%s','%s')", strPath.c_str(), scraper->ID().c_str(), ADDON::TranslateContent(scraper->Content()).c_str(), scraper->GetPathSettings().c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } @@ -4567,7 +4567,7 @@ bool CMusicDatabase::GetScraperForPath(const std::string& strPath, ADDON::Scrape if (NULL == m_pDS.get()) return false; std::string strSQL = PrepareSQL("select * from content where strPath='%s'",strPath.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->eof()) // no info set for path - fallback logic commencing { CQueryParams params; @@ -4575,27 +4575,27 @@ bool CMusicDatabase::GetScraperForPath(const std::string& strPath, ADDON::Scrape if (params.GetGenreId() != -1) // check genre { strSQL = PrepareSQL("select * from content where strPath='musicdb://genres/%i/'",params.GetGenreId()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); } if (m_pDS->eof() && params.GetAlbumId() != -1) // check album { strSQL = PrepareSQL("select * from content where strPath='musicdb://albums/%i/'",params.GetAlbumId()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->eof()) // general albums setting { strSQL = PrepareSQL("select * from content where strPath='musicdb://albums/'"); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); } } if (m_pDS->eof() && params.GetArtistId() != -1) // check artist { strSQL = PrepareSQL("select * from content where strPath='musicdb://artists/%i/'",params.GetArtistId()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->eof()) // general artist setting { strSQL = PrepareSQL("select * from content where strPath='musicdb://artists/'"); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); } } } @@ -4657,7 +4657,7 @@ bool CMusicDatabase::ScraperInUse(const std::string &scraperID) const if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("select count(1) from content where strScraperPath='%s'",scraperID.c_str()); - if (!m_pDS->query(sql.c_str()) || m_pDS->num_rows() == 0) + if (!m_pDS->query(sql) || m_pDS->num_rows() == 0) return false; bool found = m_pDS->fv(0).get_asInt() > 0; m_pDS->close(); @@ -4722,7 +4722,7 @@ void CMusicDatabase::ExportToXML(const std::string &xmlFile, bool singleFiles, b // find all albums std::vector<int> albumIds; std::string sql = "select idAlbum FROM album WHERE lastScraped IS NOT NULL"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); int total = m_pDS->num_rows(); int current = 0; @@ -4813,7 +4813,7 @@ void CMusicDatabase::ExportToXML(const std::string &xmlFile, bool singleFiles, b // find all artists std::vector<int> artistIds; std::string artistSQL = "SELECT idArtist FROM artist where lastScraped IS NOT NULL"; - m_pDS->query(artistSQL.c_str()); + m_pDS->query(artistSQL); total = m_pDS->num_rows(); current = 0; artistIds.reserve(total); @@ -5023,13 +5023,13 @@ void CMusicDatabase::AddKaraokeData(int idSong, int iKaraokeNumber) if (iKaraokeNumber > 0) { std::string strSQL = PrepareSQL("UPDATE karaokedata SET idSong=%i WHERE iKaraNumber=%i", idSong, iKaraokeNumber); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return; } // Get the maximum number allocated strSQL=PrepareSQL( "SELECT MAX(iKaraNumber) FROM karaokedata" ); - if (!m_pDS->query(strSQL.c_str())) return; + if (!m_pDS->query(strSQL)) return; int iKaraokeNumber = g_advancedSettings.m_karaokeStartIndex; @@ -5040,7 +5040,7 @@ void CMusicDatabase::AddKaraokeData(int idSong, int iKaraokeNumber) strSQL=PrepareSQL( "INSERT INTO karaokedata (iKaraNumber, idSong, iKaraDelay, strKaraEncoding, strKaralyrics) " "VALUES( %i, %i, 0, NULL, NULL)", iKaraokeNumber, idSong ); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -5058,7 +5058,7 @@ bool CMusicDatabase::GetSongByKaraokeNumber(int number, CSong & song) std::string strSQL=PrepareSQL("SELECT * FROM karaokedata where iKaraNumber=%ld", number); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) { m_pDS->close(); @@ -5088,7 +5088,7 @@ void CMusicDatabase::ExportKaraokeInfo(const std::string & outFile, bool asHTML) // find all karaoke songs std::string sql = "SELECT * FROM songview WHERE iKaraNumber > 0 ORDER BY strFileName"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); int total = m_pDS->num_rows(); int current = 0; @@ -5269,7 +5269,7 @@ void CMusicDatabase::ImportKaraokeInfo(const std::string & inputFile) std::string strSQL=PrepareSQL("select idSong from songview " "where strArtists like '%s' and strTitle like '%s'", artist, title ); - if ( !m_pDS->query(strSQL.c_str()) ) + if ( !m_pDS->query(strSQL) ) { RollbackTransaction(); if (progress) @@ -5288,7 +5288,7 @@ void CMusicDatabase::ImportKaraokeInfo(const std::string & inputFile) int lResult = m_pDS->fv(0).get_asInt(); strSQL = PrepareSQL("UPDATE karaokedata SET iKaraNumber=%i WHERE idSong=%i", num, lResult ); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); if ( progress && (offset * 100 / buf.size()) != lastpercentage ) { @@ -5327,7 +5327,7 @@ bool CMusicDatabase::SetKaraokeSongDelay(int idSong, int delay) if (NULL == m_pDS.get()) return false; std::string strSQL = PrepareSQL("UPDATE karaokedata SET iKaraDelay=%i WHERE idSong=%i", delay, idSong); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } @@ -5446,19 +5446,19 @@ void CMusicDatabase::SetArtForItem(int mediaId, const std::string &mediaType, co return; std::string sql = PrepareSQL("SELECT art_id FROM art WHERE media_id=%i AND media_type='%s' AND type='%s'", mediaId, mediaType.c_str(), artType.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // update int artId = m_pDS->fv(0).get_asInt(); m_pDS->close(); sql = PrepareSQL("UPDATE art SET url='%s' where art_id=%d", url.c_str(), artId); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } else { // insert m_pDS->close(); sql = PrepareSQL("INSERT INTO art(media_id, media_type, type, url) VALUES (%d, '%s', '%s', '%s')", mediaId, mediaType.c_str(), artType.c_str(), url.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } } catch (...) @@ -5475,7 +5475,7 @@ bool CMusicDatabase::GetArtForItem(int mediaId, const std::string &mediaType, st if (NULL == m_pDS2.get()) return false; // using dataset 2 as we're likely called in loops on dataset 1 std::string sql = PrepareSQL("SELECT type,url FROM art WHERE media_id=%i AND media_type='%s'", mediaId, mediaType.c_str()); - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); while (!m_pDS2->eof()) { art.insert(std::make_pair(m_pDS2->fv(0).get_asString(), m_pDS2->fv(1).get_asString())); @@ -5505,7 +5505,7 @@ bool CMusicDatabase::GetArtistArtForItem(int mediaId, const std::string &mediaTy if (NULL == m_pDS2.get()) return false; // using dataset 2 as we're likely called in loops on dataset 1 std::string sql = PrepareSQL("SELECT type,url FROM art WHERE media_id=(SELECT idArtist from %s_artist WHERE id%s=%i AND iOrder=0) AND media_type='artist'", mediaType.c_str(), mediaType.c_str(), mediaId); - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); while (!m_pDS2->eof()) { art.insert(std::make_pair(m_pDS2->fv(0).get_asString(), m_pDS2->fv(1).get_asString())); diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h index e755394f2c..ef497c0e86 100644 --- a/xbmc/music/MusicDatabase.h +++ b/xbmc/music/MusicDatabase.h @@ -22,11 +22,13 @@ \brief */ #pragma once -#include "dbwrappers/Database.h" -#include "Album.h" +#include <utility> + #include "addons/Scraper.h" -#include "utils/SortUtils.h" +#include "Album.h" +#include "dbwrappers/Database.h" #include "MusicDbUrl.h" +#include "utils/SortUtils.h" class CArtist; class CFileItem; diff --git a/xbmc/music/MusicThumbLoader.cpp b/xbmc/music/MusicThumbLoader.cpp index c8b47d9a02..8df7cd3d42 100644 --- a/xbmc/music/MusicThumbLoader.cpp +++ b/xbmc/music/MusicThumbLoader.cpp @@ -19,11 +19,14 @@ */ #include "MusicThumbLoader.h" + +#include <utility> + #include "FileItem.h" -#include "TextureDatabase.h" +#include "music/infoscanner/MusicInfoScanner.h" #include "music/tags/MusicInfoTag.h" #include "music/tags/MusicInfoTagLoaderFactory.h" -#include "music/infoscanner/MusicInfoScanner.h" +#include "TextureDatabase.h" #include "video/VideoThumbLoader.h" using namespace MUSIC_INFO; diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp index 0ae60a9a05..4dd5b8a217 100644 --- a/xbmc/music/infoscanner/MusicInfoScanner.cpp +++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp @@ -18,43 +18,45 @@ * */ -#include "threads/SystemClock.h" #include "MusicInfoScanner.h" -#include "music/tags/MusicInfoTagLoaderFactory.h" -#include "MusicAlbumInfo.h" -#include "MusicInfoScraper.h" + +#include <algorithm> +#include <utility> + +#include "addons/AddonManager.h" +#include "addons/Scraper.h" +#include "dialogs/GUIDialogExtendedProgressBar.h" +#include "dialogs/GUIDialogProgress.h" +#include "dialogs/GUIDialogSelect.h" #include "events/EventLog.h" #include "events/MediaLibraryEvent.h" +#include "FileItem.h" +#include "filesystem/Directory.h" +#include "filesystem/File.h" #include "filesystem/MusicDatabaseDirectory.h" #include "filesystem/MusicDatabaseDirectory/DirectoryNode.h" -#include "Util.h" -#include "utils/md5.h" #include "GUIInfoManager.h" -#include "NfoFile.h" -#include "music/tags/MusicInfoTag.h" -#include "guilib/GUIWindowManager.h" -#include "dialogs/GUIDialogExtendedProgressBar.h" -#include "dialogs/GUIDialogProgress.h" -#include "dialogs/GUIDialogSelect.h" #include "guilib/GUIKeyboardFactory.h" -#include "filesystem/File.h" -#include "filesystem/Directory.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "GUIUserMessages.h" +#include "interfaces/AnnouncementManager.h" +#include "music/MusicThumbLoader.h" +#include "music/tags/MusicInfoTag.h" +#include "music/tags/MusicInfoTagLoaderFactory.h" +#include "MusicAlbumInfo.h" +#include "MusicInfoScraper.h" +#include "NfoFile.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" -#include "FileItem.h" -#include "guilib/LocalizeStrings.h" -#include "utils/StringUtils.h" +#include "TextureCache.h" +#include "threads/SystemClock.h" +#include "Util.h" #include "utils/log.h" +#include "utils/md5.h" +#include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" -#include "TextureCache.h" -#include "music/MusicThumbLoader.h" -#include "interfaces/AnnouncementManager.h" -#include "GUIUserMessages.h" -#include "addons/AddonManager.h" -#include "addons/Scraper.h" - -#include <algorithm> using namespace MUSIC_INFO; using namespace XFILE; diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp index b0926c8e29..c27bf07a36 100644 --- a/xbmc/network/AirTunesServer.cpp +++ b/xbmc/network/AirTunesServer.cpp @@ -21,43 +21,45 @@ * */ -#include "network/Network.h" -#if !defined(TARGET_WINDOWS) -#pragma GCC diagnostic ignored "-Wwrite-strings" -#endif +#include "system.h" +#ifdef HAS_AIRTUNES #include "AirTunesServer.h" -#ifdef HAS_AIRPLAY -#include "network/AirPlayServer.h" -#endif - -#ifdef HAS_AIRTUNES +#include <map> +#include <string> +#include <utility> -#include "utils/log.h" -#include "network/Zeroconf.h" -#include "messaging/ApplicationMessenger.h" -#include "filesystem/PipeFile.h" #include "Application.h" #include "cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h" -#include "filesystem/File.h" -#include "music/tags/MusicInfoTag.h" #include "FileItem.h" +#include "filesystem/File.h" +#include "filesystem/PipeFile.h" #include "GUIInfoManager.h" #include "guilib/GUIWindowManager.h" -#include "utils/Variant.h" -#include "utils/SystemInfo.h" -#include "utils/StringUtils.h" +#include "interfaces/AnnouncementManager.h" +#include "messaging/ApplicationMessenger.h" +#include "music/tags/MusicInfoTag.h" +#include "network/dacp/dacp.h" +#include "network/Network.h" +#include "network/Zeroconf.h" +#include "network/ZeroconfBrowser.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" -#include "utils/EndianSwap.h" #include "URL.h" -#include "interfaces/AnnouncementManager.h" -#include "network/ZeroconfBrowser.h" -#include "network/dacp/dacp.h" +#include "utils/EndianSwap.h" +#include "utils/log.h" +#include "utils/StringUtils.h" +#include "utils/SystemInfo.h" +#include "utils/Variant.h" -#include <map> -#include <string> +#if !defined(TARGET_WINDOWS) +#pragma GCC diagnostic ignored "-Wwrite-strings" +#endif + +#ifdef HAS_AIRPLAY +#include "network/AirPlayServer.h" +#endif #define TMP_COVERART_PATH_JPG "special://temp/airtunes_album_thumb.jpg" #define TMP_COVERART_PATH_PNG "special://temp/airtunes_album_thumb.png" @@ -354,7 +356,7 @@ void CAirTunesServer::AudioOutputFunctions::audio_set_coverart(void *cls, void * CAirTunesServer::SetCoverArtFromBuffer((char *)buffer, buflen); } -char *session="Kodi-AirTunes"; +char session[]="Kodi-AirTunes"; void* CAirTunesServer::AudioOutputFunctions::audio_init(void *cls, int bits, int channels, int samplerate) { diff --git a/xbmc/network/GUIDialogNetworkSetup.cpp b/xbmc/network/GUIDialogNetworkSetup.cpp index ab6d77c098..206c597218 100644 --- a/xbmc/network/GUIDialogNetworkSetup.cpp +++ b/xbmc/network/GUIDialogNetworkSetup.cpp @@ -19,13 +19,16 @@ */ #include "GUIDialogNetworkSetup.h" + +#include <utility> + #include "dialogs/GUIDialogFileBrowser.h" -#include "guilib/GUIWindowManager.h" #include "guilib/GUIEditControl.h" -#include "utils/URIUtils.h" -#include "utils/StringUtils.h" -#include "URL.h" +#include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" +#include "URL.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" #define CONTROL_PROTOCOL 10 #define CONTROL_SERVER_ADDRESS 11 diff --git a/xbmc/network/NetworkServices.cpp b/xbmc/network/NetworkServices.cpp index 67474c4172..9cb9845e0a 100644 --- a/xbmc/network/NetworkServices.cpp +++ b/xbmc/network/NetworkServices.cpp @@ -19,17 +19,27 @@ */ #include "NetworkServices.h" + +#include <utility> + #include "Application.h" -#include "messaging/ApplicationMessenger.h" -#include "messaging/helpers/DialogHelper.h" -#ifdef TARGET_LINUX -#include "Util.h" -#endif #include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogOK.h" #include "guilib/LocalizeStrings.h" +#include "messaging/ApplicationMessenger.h" +#include "messaging/helpers/DialogHelper.h" #include "network/Network.h" +#include "settings/AdvancedSettings.h" +#include "settings/lib/Setting.h" +#include "settings/Settings.h" +#include "utils/log.h" +#include "utils/RssManager.h" +#include "utils/SystemInfo.h" +#include "utils/Variant.h" +#ifdef TARGET_LINUX +#include "Util.h" +#endif #ifdef HAS_AIRPLAY #include "network/AirPlayServer.h" #endif // HAS_AIRPLAY @@ -76,14 +86,6 @@ #include "osx/XBMCHelper.h" #endif -#include "settings/AdvancedSettings.h" -#include "settings/lib/Setting.h" -#include "settings/Settings.h" -#include "utils/log.h" -#include "utils/RssManager.h" -#include "utils/SystemInfo.h" -#include "utils/Variant.h" - using namespace KODI::MESSAGING; #ifdef HAS_JSONRPC using namespace JSONRPC; diff --git a/xbmc/network/WebServer.cpp b/xbmc/network/WebServer.cpp index 11efc998ba..b79b077460 100644 --- a/xbmc/network/WebServer.cpp +++ b/xbmc/network/WebServer.cpp @@ -25,23 +25,24 @@ #include "WebServer.h" #ifdef HAS_WEB_SERVER -#include <memory> #include <algorithm> +#include <memory> #include <stdexcept> +#include <utility> -#include "URL.h" -#include "Util.h" -#include "XBDateTime.h" #include "filesystem/File.h" #include "network/httprequesthandler/IHTTPRequestHandler.h" #include "settings/Settings.h" #include "threads/SingleLock.h" +#include "URL.h" +#include "Util.h" #include "utils/Base64.h" #include "utils/log.h" #include "utils/Mime.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" +#include "XBDateTime.h" //#define WEBSERVER_DEBUG diff --git a/xbmc/network/Zeroconf.cpp b/xbmc/network/Zeroconf.cpp index 5288f380f7..41bec11dc6 100644 --- a/xbmc/network/Zeroconf.cpp +++ b/xbmc/network/Zeroconf.cpp @@ -17,10 +17,16 @@ * <http://www.gnu.org/licenses/>. * */ -#include "system.h" //HAS_ZEROCONF define -#include <assert.h> #include "Zeroconf.h" + +#include <cassert> + #include "settings/Settings.h" +#include "system.h" //HAS_ZEROCONF define +#include "threads/Atomics.h" +#include "threads/CriticalSection.h" +#include "threads/SingleLock.h" +#include "utils/JobManager.h" #if defined(HAS_AVAHI) #include "linux/ZeroconfAvahi.h" @@ -31,11 +37,6 @@ #include "mdns/ZeroconfMDNS.h" #endif -#include "threads/CriticalSection.h" -#include "threads/SingleLock.h" -#include "threads/Atomics.h" -#include "utils/JobManager.h" - #ifndef HAS_ZEROCONF //dummy implementation used if no zeroconf is present //should be optimized away diff --git a/xbmc/network/Zeroconf.h b/xbmc/network/Zeroconf.h index d87e34ceff..f4aca4be32 100644 --- a/xbmc/network/Zeroconf.h +++ b/xbmc/network/Zeroconf.h @@ -20,9 +20,11 @@ * */ -#include <string> #include <map> +#include <string> +#include <utility> #include <vector> + #include "utils/Job.h" class CCriticalSection; diff --git a/xbmc/network/cddb.cpp b/xbmc/network/cddb.cpp index 4515dea3d0..b83fc60f38 100644 --- a/xbmc/network/cddb.cpp +++ b/xbmc/network/cddb.cpp @@ -52,7 +52,11 @@ using namespace CDDB; //------------------------------------------------------------------------------------------------------------------- Xcddb::Xcddb() - : m_cddb_socket(INVALID_SOCKET) +#if defined(TARGET_WINDOWS) + : m_cddb_socket(closesocket, INVALID_SOCKET) +#else + : m_cddb_socket(close, -1) +#endif , m_cddb_ip_adress(g_advancedSettings.m_cddbAddress) { m_lastError = 0; @@ -123,7 +127,7 @@ bool Xcddb::openSocket() //------------------------------------------------------------------------------------------------------------------- bool Xcddb::closeSocket() { - if ( m_cddb_socket.isValid() ) + if (m_cddb_socket) { m_cddb_socket.reset(); } diff --git a/xbmc/network/cddb.h b/xbmc/network/cddb.h index 4b6fc4f050..513a74e0b4 100644 --- a/xbmc/network/cddb.h +++ b/xbmc/network/cddb.h @@ -32,7 +32,7 @@ #endif #include "storage/cdioSupport.h" -#include "utils/AutoPtrHandle.h" +#include "utils/ScopeGuard.h" namespace CDDB { @@ -92,7 +92,12 @@ public: protected: std::string m_strNull; - AUTOPTR::CAutoPtrSocket m_cddb_socket; +#if defined(TARGET_WINDOWS) + using CAutoPtrSocket = KODI::UTILS::CScopeGuard<SOCKET, INVALID_SOCKET, decltype(closesocket)>; +#else + using CAutoPtrSocket = KODI::UTILS::CScopeGuard<int, -1, decltype(close)>; +#endif + CAutoPtrSocket m_cddb_socket; const static int recv_buffer = 4096; int m_lastError; std::map<int, std::string> m_mapTitles; diff --git a/xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp b/xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp index d338ead7a8..3d3571d429 100644 --- a/xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp +++ b/xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp @@ -24,6 +24,8 @@ #include "network/WebServer.h" #include "utils/StringUtils.h" +#include <utility> + IHTTPRequestHandler::IHTTPRequestHandler() : m_request(), m_response(), diff --git a/xbmc/network/httprequesthandler/IHTTPRequestHandler.h b/xbmc/network/httprequesthandler/IHTTPRequestHandler.h index 5205c5844f..e25dc441a5 100644 --- a/xbmc/network/httprequesthandler/IHTTPRequestHandler.h +++ b/xbmc/network/httprequesthandler/IHTTPRequestHandler.h @@ -19,9 +19,6 @@ * */ -#include <string> -#include <map> - #include <sys/types.h> #include <sys/select.h> #include <sys/socket.h> @@ -29,6 +26,9 @@ #include <string.h> #include <stdio.h> #include <stdint.h> +#include <map> +#include <string> + #include <microhttpd.h> #include "utils/HttpRangeUtils.h" diff --git a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp index dc3bf1cd1f..85e5c9ad26 100644 --- a/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp +++ b/xbmc/network/httprequesthandler/python/HTTPPythonWsgiInvoker.cpp @@ -18,14 +18,16 @@ * */ -#include "interfaces/python/swig.h" - #include "HTTPPythonWsgiInvoker.h" -#include "URL.h" + +#include <utility> + #include "addons/Webinterface.h" #include "interfaces/legacy/wsgi/WsgiErrorStream.h" #include "interfaces/legacy/wsgi/WsgiInputStream.h" #include "interfaces/legacy/wsgi/WsgiResponse.h" +#include "interfaces/python/swig.h" +#include "URL.h" #include "utils/URIUtils.h" #define MODULE "xbmc" diff --git a/xbmc/network/mdns/ZeroconfBrowserMDNS.cpp b/xbmc/network/mdns/ZeroconfBrowserMDNS.cpp index dd02715b71..51b9c37054 100644 --- a/xbmc/network/mdns/ZeroconfBrowserMDNS.cpp +++ b/xbmc/network/mdns/ZeroconfBrowserMDNS.cpp @@ -19,17 +19,21 @@ */ #include "ZeroconfBrowserMDNS.h" -#include <utils/log.h> -#include <threads/SingleLock.h> -#include "guilib/GUIWindowManager.h" + +#include <netinet/in.h> +#include <arpa/inet.h> + #include "guilib/GUIMessage.h" +#include "guilib/GUIWindowManager.h" #include "GUIUserMessages.h" +#include "network/DNSNameCache.h" +#include "system.h" +#include "threads/SingleLock.h" +#include "utils/log.h" + #if defined(TARGET_WINDOWS) #include "win32/WIN32Util.h" #endif //TARGET_WINDOWS -#include "network/DNSNameCache.h" -#include <netinet/in.h> -#include <arpa/inet.h> #pragma comment(lib, "dnssd.lib") diff --git a/xbmc/network/mdns/ZeroconfBrowserMDNS.h b/xbmc/network/mdns/ZeroconfBrowserMDNS.h index ad5d46ad8e..fb35106760 100644 --- a/xbmc/network/mdns/ZeroconfBrowserMDNS.h +++ b/xbmc/network/mdns/ZeroconfBrowserMDNS.h @@ -19,13 +19,15 @@ */ #pragma once -#include <memory> #include <map> +#include <memory> +#include <utility> + +#include <dns_sd.h> #include "network/ZeroconfBrowser.h" -#include "threads/Thread.h" #include "threads/CriticalSection.h" -#include <dns_sd.h> +#include "threads/Thread.h" //platform specific implementation of zeroconfbrowser interface using native os x APIs class CZeroconfBrowserMDNS : public CZeroconfBrowser diff --git a/xbmc/network/mdns/ZeroconfMDNS.h b/xbmc/network/mdns/ZeroconfMDNS.h index 01566916a9..e6360abb2c 100644 --- a/xbmc/network/mdns/ZeroconfMDNS.h +++ b/xbmc/network/mdns/ZeroconfMDNS.h @@ -19,13 +19,14 @@ */ #pragma once -#include <memory> - #include "network/Zeroconf.h" #include "threads/CriticalSection.h" #include <dns_sd.h> #include "threads/Thread.h" +#include <memory> +#include <utility> + class CZeroconfMDNS : public CZeroconf,public CThread { public: diff --git a/xbmc/network/upnp/UPnPServer.h b/xbmc/network/upnp/UPnPServer.h index 294aea59a3..469b2301bb 100644 --- a/xbmc/network/upnp/UPnPServer.h +++ b/xbmc/network/upnp/UPnPServer.h @@ -18,10 +18,11 @@ * */ #pragma once +#include <utility> #include <Platinum/Source/Devices/MediaConnect/PltMediaConnect.h> -#include "interfaces/IAnnouncer.h" #include "FileItem.h" +#include "interfaces/IAnnouncer.h" class CVariant; class CThumbLoader; diff --git a/xbmc/osx/DarwinUtils.h b/xbmc/osx/DarwinUtils.h index 77635489fe..45ac468b13 100644 --- a/xbmc/osx/DarwinUtils.h +++ b/xbmc/osx/DarwinUtils.h @@ -35,6 +35,7 @@ public: static bool IsMavericks(void); static bool IsSnowLeopard(void); static bool DeviceHasRetina(double &scale); + static bool DeviceHasLeakyVDA(void); static const char *GetOSReleaseString(void); static const char *GetOSVersionString(void); static float GetIOSVersion(void); diff --git a/xbmc/osx/DarwinUtils.mm b/xbmc/osx/DarwinUtils.mm index 8d836dcf77..02df83f0a7 100644 --- a/xbmc/osx/DarwinUtils.mm +++ b/xbmc/osx/DarwinUtils.mm @@ -53,6 +53,11 @@ #define NSAppKitVersionNumber10_6 1038 #endif +#ifndef NSAppKitVersionNumber10_9 +#define NSAppKitVersionNumber10_9 1265 +#endif + + enum iosPlatform { iDeviceUnknown = -1, @@ -251,6 +256,16 @@ bool CDarwinUtils::DeviceHasRetina(double &scale) return (platform >= iPhone4); } +bool CDarwinUtils::DeviceHasLeakyVDA(void) +{ + static int hasLeakyVDA = -1; +#if defined(TARGET_DARWIN_OSX) + if (hasLeakyVDA == -1) + hasLeakyVDA = NSAppKitVersionNumber <= NSAppKitVersionNumber10_9 ? 1 : 0; +#endif + return hasLeakyVDA == 1; +} + const char *CDarwinUtils::GetOSReleaseString(void) { static std::string osreleaseStr; diff --git a/xbmc/osx/IOSEAGLView.mm b/xbmc/osx/IOSEAGLView.mm index fd9f64d056..c451d95df2 100644 --- a/xbmc/osx/IOSEAGLView.mm +++ b/xbmc/osx/IOSEAGLView.mm @@ -372,6 +372,9 @@ using namespace KODI::MESSAGING; - (void) runAnimation:(id) arg { CCocoaAutoPool outerpool; + + [[NSThread currentThread] setName:@"XBMC_Run"]; + // set up some xbmc specific relationships XBMC::Context context; readyToRun = true; diff --git a/xbmc/osx/ios/XBMCController.mm b/xbmc/osx/ios/XBMCController.mm index 3d1393fc55..c73ac6e41d 100644 --- a/xbmc/osx/ios/XBMCController.mm +++ b/xbmc/osx/ios/XBMCController.mm @@ -398,32 +398,33 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL; [swipe release]; } //-------------------------------------------------------------- -- (void)createGestureRecognizers +- (void)addTapGesture:(NSUInteger)numTouches { - //1 finger single tab - UITapGestureRecognizer *singleFingerSingleTap = [[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(handleSingleFingerSingleTap:)]; + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] + initWithTarget:self action:@selector(handleTap:)]; - singleFingerSingleTap.delaysTouchesBegan = NO; - singleFingerSingleTap.numberOfTapsRequired = 1; - singleFingerSingleTap.numberOfTouchesRequired = 1; + tapGesture.delaysTouchesBegan = NO; + tapGesture.numberOfTapsRequired = 1; + tapGesture.numberOfTouchesRequired = numTouches; - [m_glView addGestureRecognizer:singleFingerSingleTap]; - [singleFingerSingleTap release]; + [m_glView addGestureRecognizer:tapGesture]; + [tapGesture release]; +} +//-------------------------------------------------------------- +- (void)createGestureRecognizers +{ + //1 finger single tap + [self addTapGesture:1]; - //2 finger single tab - right mouse - //single finger double tab delays single finger single tab - so we + //2 finger single tap - right mouse + //single finger double tap delays single finger single tap - so we //go for 2 fingers here - so single finger single tap is instant - UITapGestureRecognizer *doubleFingerSingleTap = [[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(handleDoubleFingerSingleTap:)]; + [self addTapGesture:2]; - doubleFingerSingleTap.delaysTouchesBegan = NO; - doubleFingerSingleTap.numberOfTapsRequired = 1; - doubleFingerSingleTap.numberOfTouchesRequired = 2; - [m_glView addGestureRecognizer:doubleFingerSingleTap]; - [doubleFingerSingleTap release]; + //3 finger single tap + [self addTapGesture:3]; - //1 finger single long tab - right mouse - alernative + //1 finger single long tap - right mouse - alernative UILongPressGestureRecognizer *singleFingerSingleLongTap = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerSingleLongTap:)]; @@ -669,11 +670,11 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL; } } //-------------------------------------------------------------- -- (IBAction)handleSingleFingerSingleTap:(UIGestureRecognizer *)sender +- (IBAction)handleTap:(UIGestureRecognizer *)sender { //Allow the tap gesture during init //(for allowing the user to tap away any messagboxes during init) - if( [m_glView isReadyToRun] ) + if( ([m_glView isReadyToRun] && [sender numberOfTouches] == 1) || [m_glView isXBMCAlive]) { CGPoint point = [sender locationOfTouch:0 inView:m_glView]; point.x *= screenScale; @@ -683,18 +684,6 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL; } } //-------------------------------------------------------------- -- (IBAction)handleDoubleFingerSingleTap:(UIGestureRecognizer *)sender -{ - if( [m_glView isXBMCAlive] )//NO GESTURES BEFORE WE ARE UP AND RUNNING - { - CGPoint point = [sender locationOfTouch:0 inView:m_glView]; - point.x *= screenScale; - point.y *= screenScale; - //NSLog(@"%s toubleTap", __PRETTY_FUNCTION__); - CGenericTouchActionHandler::GetInstance().OnTap((float)point.x, (float)point.y, [sender numberOfTouches]); - } -} -//-------------------------------------------------------------- - (IBAction)handleSingleFingerSingleLongTap:(UIGestureRecognizer *)sender { if( [m_glView isXBMCAlive] )//NO GESTURES BEFORE WE ARE UP AND RUNNING diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp index 235e4b224c..d7d275e525 100644 --- a/xbmc/peripherals/Peripherals.cpp +++ b/xbmc/peripherals/Peripherals.cpp @@ -19,40 +19,43 @@ */ #include "Peripherals.h" + +#include <utility> + #include "bus/PeripheralBus.h" +#include "bus/PeripheralBusUSB.h" #include "devices/PeripheralBluetooth.h" +#include "devices/PeripheralCecAdapter.h" #include "devices/PeripheralDisk.h" #include "devices/PeripheralHID.h" +#include "devices/PeripheralImon.h" #include "devices/PeripheralNIC.h" #include "devices/PeripheralNyxboard.h" #include "devices/PeripheralTuner.h" -#include "devices/PeripheralCecAdapter.h" -#include "devices/PeripheralImon.h" -#include "bus/PeripheralBusUSB.h" +#include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogPeripheralSettings.h" #include "dialogs/GUIDialogSelect.h" - -#if defined(HAVE_LIBCEC) -#include "bus/virtual/PeripheralBusCEC.h" -#endif - #include "FileItem.h" -#include "threads/SingleLock.h" -#include "utils/log.h" -#include "utils/XMLUtils.h" -#include "utils/XBMCTinyXML.h" #include "filesystem/Directory.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" -#include "dialogs/GUIDialogKaiToast.h" #include "GUIUserMessages.h" -#include "utils/StringUtils.h" -#include "Util.h" #include "input/Key.h" +#include "messaging/ApplicationMessenger.h" +#include "messaging/ThreadMessage.h" #include "settings/lib/Setting.h" #include "settings/Settings.h" -#include "messaging/ThreadMessage.h" -#include "messaging/ApplicationMessenger.h" +#include "threads/SingleLock.h" +#include "Util.h" +#include "utils/log.h" +#include "utils/StringUtils.h" +#include "utils/XBMCTinyXML.h" +#include "utils/XMLUtils.h" + +#if defined(HAVE_LIBCEC) +#include "bus/virtual/PeripheralBusCEC.h" +#endif + using namespace PERIPHERALS; using namespace XFILE; diff --git a/xbmc/peripherals/Peripherals.h b/xbmc/peripherals/Peripherals.h index aeabef7774..39c9f17d53 100644 --- a/xbmc/peripherals/Peripherals.h +++ b/xbmc/peripherals/Peripherals.h @@ -19,14 +19,14 @@ * */ -#include "system.h" #include "bus/PeripheralBus.h" #include "devices/Peripheral.h" +#include "messaging/IMessageTarget.h" #include "settings/lib/ISettingCallback.h" +#include "system.h" #include "threads/CriticalSection.h" #include "threads/Thread.h" #include "utils/Observer.h" -#include "messaging/IMessageTarget.h" class CFileItemList; class CSetting; diff --git a/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp index 0ab954807a..0d83865c84 100644 --- a/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp +++ b/xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp @@ -121,7 +121,7 @@ void CPeripheralBusUSB::DeviceDetachCallback(void *refCon, io_service_t service, { if (messageType == kIOMessageServiceIsTerminated) { - USBDevicePrivateData *privateDataRef = (USBDevicePrivateData*)refCon; + std::unique_ptr<USBDevicePrivateData> privateDataRef((USBDevicePrivateData*)refCon); std::vector<PeripheralScanResult>::iterator it = privateDataRef->refCon->m_scan_results.m_results.begin(); while(it != privateDataRef->refCon->m_scan_results.m_results.end()) @@ -136,7 +136,6 @@ void CPeripheralBusUSB::DeviceDetachCallback(void *refCon, io_service_t service, CLog::Log(LOGDEBUG, "USB Device Detach:%s, %s\n", privateDataRef->deviceName.c_str(), privateDataRef->result.m_strLocation.c_str()); IOObjectRelease(privateDataRef->notification); - delete privateDataRef; //release the service IOObjectRelease(service); } @@ -175,6 +174,9 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera continue; } + // do not need the intermediate plug-in after device interface is created + (*devicePlugin)->Release(devicePlugin); + // get vendor/product ids UInt16 vendorId; UInt16 productId; @@ -216,6 +218,9 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera continue; } + // do not need the intermediate plug-in after query + (*interfaceInterface)->Release(interfaceInterface); + // finally we can get to the bInterfaceClass // we should also check for kHIDKeyboardInterfaceProtocol but // some IR remotes that emulate an HID keyboard do not report this. @@ -225,8 +230,7 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera { std::string ttlDeviceFilePath; CFStringRef deviceFilePathAsCFString; - USBDevicePrivateData *privateDataRef; - privateDataRef = new USBDevicePrivateData; + std::unique_ptr<USBDevicePrivateData> privateDataRef(new USBDevicePrivateData); // save the device info to our private data. privateDataRef->refCon = refCon; privateDataRef->deviceName = deviceName; @@ -273,7 +277,7 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera usbDevice, // service kIOGeneralInterest, // interestType (IOServiceInterestCallback)DeviceDetachCallback, // callback - privateDataRef, // refCon + &privateDataRef, // refCon &privateDataRef->notification); // notification if (result == kIOReturnSuccess) @@ -282,14 +286,6 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera CLog::Log(LOGDEBUG, "USB Device Attach:%s, %s\n", deviceName, privateDataRef->result.m_strLocation.c_str()); } - else - { - delete privateDataRef; - } - } - else - { - delete privateDataRef; } // done with this device, only need one notification per device. IODestroyPlugInInterface(interfacePlugin); diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp index b3a38324c4..4ae87893da 100644 --- a/xbmc/peripherals/devices/Peripheral.cpp +++ b/xbmc/peripherals/devices/Peripheral.cpp @@ -19,13 +19,16 @@ */ #include "Peripheral.h" + +#include <utility> + +#include "guilib/LocalizeStrings.h" #include "peripherals/Peripherals.h" +#include "settings/lib/Setting.h" #include "utils/log.h" #include "utils/StringUtils.h" -#include "settings/lib/Setting.h" #include "utils/XBMCTinyXML.h" #include "utils/XMLUtils.h" -#include "guilib/LocalizeStrings.h" using namespace PERIPHERALS; diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp index abe2c19567..accd6646b2 100644 --- a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp +++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp @@ -19,9 +19,12 @@ */ #include "GUIDialogPeripheralSettings.h" -#include "FileItem.h" + +#include <utility> + #include "addons/Skin.h" #include "dialogs/GUIDialogYesNo.h" +#include "FileItem.h" #include "peripherals/Peripherals.h" #include "settings/lib/Setting.h" #include "settings/lib/SettingSection.h" diff --git a/xbmc/pictures/GUIWindowSlideShow.cpp b/xbmc/pictures/GUIWindowSlideShow.cpp index bcc8b73bfe..bb8e551dcd 100644 --- a/xbmc/pictures/GUIWindowSlideShow.cpp +++ b/xbmc/pictures/GUIWindowSlideShow.cpp @@ -261,8 +261,6 @@ void CGUIWindowSlideShow::OnDeinitWindow(int nextWindowID) if (nextWindowID != WINDOW_PICTURES) m_ImageLib.Unload(); - g_windowManager.ShowOverlay(OVERLAY_STATE_SHOWN); - if (nextWindowID != WINDOW_FULLSCREEN_VIDEO) { // wait for any outstanding picture loads @@ -935,8 +933,6 @@ bool CGUIWindowSlideShow::OnMessage(CGUIMessage& message) if (message.GetParam1() != WINDOW_PICTURES) m_ImageLib.Load(); - g_windowManager.ShowOverlay(OVERLAY_STATE_HIDDEN); - // turn off slideshow if we only have 1 image if (m_slides->Size() <= 1) m_bSlideShow = false; diff --git a/xbmc/powermanagement/PowerManager.cpp b/xbmc/powermanagement/PowerManager.cpp index 845105e0cd..7c5604d70a 100644 --- a/xbmc/powermanagement/PowerManager.cpp +++ b/xbmc/powermanagement/PowerManager.cpp @@ -18,24 +18,26 @@ * */ -#include <memory> -#include <list> -#include "system.h" #include "PowerManager.h" + +#include <list> +#include <memory> + #include "Application.h" #include "cores/AudioEngine/AEFactory.h" +#include "dialogs/GUIDialogBusy.h" +#include "dialogs/GUIDialogKaiToast.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "interfaces/AnnouncementManager.h" +#include "interfaces/builtins/Builtins.h" +#include "pvr/PVRManager.h" #include "settings/lib/Setting.h" #include "settings/Settings.h" -#include "windowing/WindowingFactory.h" +#include "system.h" #include "utils/log.h" #include "utils/Weather.h" -#include "interfaces/builtins/Builtins.h" -#include "interfaces/AnnouncementManager.h" -#include "guilib/LocalizeStrings.h" -#include "guilib/GUIWindowManager.h" -#include "dialogs/GUIDialogBusy.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "pvr/PVRManager.h" +#include "windowing/WindowingFactory.h" #if defined(TARGET_DARWIN) #include "osx/CocoaPowerSyscall.h" diff --git a/xbmc/powermanagement/PowerManager.h b/xbmc/powermanagement/PowerManager.h index e984da1d86..b03e20bb9e 100644 --- a/xbmc/powermanagement/PowerManager.h +++ b/xbmc/powermanagement/PowerManager.h @@ -22,6 +22,7 @@ #define _POWER_MANAGER_H_ #include <string> +#include <utility> #include <vector> #include "IPowerSyscall.h" diff --git a/xbmc/profiles/dialogs/GUIDialogLockSettings.cpp b/xbmc/profiles/dialogs/GUIDialogLockSettings.cpp index 3c6fea1a5c..078ad75b84 100644 --- a/xbmc/profiles/dialogs/GUIDialogLockSettings.cpp +++ b/xbmc/profiles/dialogs/GUIDialogLockSettings.cpp @@ -19,16 +19,19 @@ */ #include "GUIDialogLockSettings.h" -#include "URL.h" + +#include <utility> + #include "dialogs/GUIDialogContextMenu.h" #include "dialogs/GUIDialogGamepad.h" -#include "guilib/GUIKeyboardFactory.h" #include "dialogs/GUIDialogNumeric.h" +#include "guilib/GUIKeyboardFactory.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" #include "settings/lib/Setting.h" #include "settings/lib/SettingSection.h" #include "settings/windows/GUIControlSettings.h" +#include "URL.h" #include "utils/log.h" #include "utils/StringUtils.h" diff --git a/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp b/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp index 212383ef06..ab80d2e551 100644 --- a/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp +++ b/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp @@ -19,20 +19,23 @@ */ #include "GUIDialogProfileSettings.h" -#include "FileItem.h" -#include "GUIPassword.h" -#include "Util.h" + +#include <utility> + #include "dialogs/GUIDialogFileBrowser.h" #include "dialogs/GUIDialogYesNo.h" +#include "FileItem.h" #include "filesystem/Directory.h" #include "filesystem/File.h" #include "guilib/GUIKeyboardFactory.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" -#include "profiles/ProfilesManager.h" +#include "GUIPassword.h" #include "profiles/dialogs/GUIDialogLockSettings.h" +#include "profiles/ProfilesManager.h" #include "settings/lib/Setting.h" #include "storage/MediaManager.h" +#include "Util.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp index 04688af3c4..8ecdd2fc71 100644 --- a/xbmc/pvr/PVRDatabase.cpp +++ b/xbmc/pvr/PVRDatabase.cpp @@ -18,19 +18,20 @@ * */ +#include "PVRDatabase.h" + +#include <utility> + #include "dbwrappers/dataset.h" +#include "pvr/addons/PVRClient.h" +#include "pvr/channels/PVRChannelGroupInternal.h" +#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/PVRManager.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "utils/log.h" #include "utils/StringUtils.h" -#include "pvr/PVRManager.h" -#include "pvr/channels/PVRChannelGroupInternal.h" -#include "pvr/channels/PVRChannelGroupsContainer.h" -#include "pvr/addons/PVRClient.h" - -#include "PVRDatabase.h" - using namespace dbiplus; using namespace PVR; using namespace ADDON; diff --git a/xbmc/pvr/PVRGUIInfo.cpp b/xbmc/pvr/PVRGUIInfo.cpp index 6feb2941c8..b174ceb038 100644 --- a/xbmc/pvr/PVRGUIInfo.cpp +++ b/xbmc/pvr/PVRGUIInfo.cpp @@ -68,10 +68,15 @@ void CPVRGUIInfo::ResetProperties(void) m_iRecordingTimerAmount = 0; m_iCurrentActiveClient = 0; m_strPlayingClientName .clear(); + m_strBackendName .clear(); + m_strBackendVersion .clear(); + m_strBackendHost .clear(); m_strBackendTimers .clear(); m_strBackendRecordings .clear(); m_strBackendDeletedRecordings .clear(); m_strBackendChannels .clear(); + m_iBackendDiskTotal = 0; + m_iBackendDiskUsed = 0; m_iTimerInfoToggleStart = 0; m_iTimerInfoToggleCurrent = 0; m_ToggleShowInfo.SetInfinite(); @@ -87,6 +92,8 @@ void CPVRGUIInfo::ResetProperties(void) ResetPlayingTag(); ClearQualityInfo(m_qualityInfo); + + m_updateBackendCacheRequested = false; } void CPVRGUIInfo::ClearQualityInfo(PVR_SIGNAL_STATUS &qualityInfo) @@ -174,6 +181,9 @@ void CPVRGUIInfo::Process(void) g_PVRTimers->RegisterObserver(this); UpdateTimersCache(); + /* update the backend cache once initially */ + m_updateBackendCacheRequested = true; + while (!g_application.m_bStop && !m_bStop) { if (!m_bStop) @@ -478,10 +488,8 @@ int CPVRGUIInfo::TranslateIntInfo(DWORD dwInfo) const iReturn = (int) ((float) m_qualityInfo.iSNR / 0xFFFF * 100); else if (dwInfo == PVR_BACKEND_DISKSPACE_PROGR) { - const auto &backend = GetCurrentActiveBackend(); - - if (backend.diskTotal > 0) - iReturn = static_cast<int>(100 * backend.diskUsed / backend.diskTotal); + if (m_iBackendDiskTotal > 0) + iReturn = static_cast<int>(100 * m_iBackendDiskUsed / m_iBackendDiskTotal); else iReturn = 0xFF; } @@ -576,7 +584,7 @@ void CPVRGUIInfo::CharInfoBackendNumber(std::string &strValue) const void CPVRGUIInfo::CharInfoTotalDiskSpace(std::string &strValue) const { - strValue = StringUtils::SizeToString(GetCurrentActiveBackend().diskTotal).c_str(); + strValue = StringUtils::SizeToString(m_iBackendDiskTotal).c_str(); } void CPVRGUIInfo::CharInfoVideoBR(std::string &strValue) const @@ -632,39 +640,28 @@ void CPVRGUIInfo::CharInfoFrontendStatus(std::string &strValue) const void CPVRGUIInfo::CharInfoBackendName(std::string &strValue) const { - const std::string &backendName = GetCurrentActiveBackend().name; - - if (backendName.empty()) - strValue = g_localizeStrings.Get(13205); - else - strValue = backendName; + m_updateBackendCacheRequested = true; + strValue = m_strBackendName; } void CPVRGUIInfo::CharInfoBackendVersion(std::string &strValue) const { - const std::string &backendVersion = GetCurrentActiveBackend().version; - - if (backendVersion.empty()) - strValue = g_localizeStrings.Get(13205); - else - strValue = backendVersion; + m_updateBackendCacheRequested = true; + strValue = m_strBackendVersion; } void CPVRGUIInfo::CharInfoBackendHost(std::string &strValue) const { - const std::string &backendHost = GetCurrentActiveBackend().host; - - if (backendHost.empty()) - strValue = g_localizeStrings.Get(13205); - else - strValue = backendHost; + m_updateBackendCacheRequested = true; + strValue = m_strBackendHost; } void CPVRGUIInfo::CharInfoBackendDiskspace(std::string &strValue) const { - const auto &backend = GetCurrentActiveBackend(); - auto diskTotal = backend.diskTotal; - auto diskUsed = backend.diskUsed; + m_updateBackendCacheRequested = true; + + auto diskTotal = m_iBackendDiskTotal; + auto diskUsed = m_iBackendDiskUsed; if (diskTotal > 0) { @@ -678,34 +675,26 @@ void CPVRGUIInfo::CharInfoBackendDiskspace(std::string &strValue) const void CPVRGUIInfo::CharInfoBackendChannels(std::string &strValue) const { - if (m_strBackendChannels.empty()) - strValue = g_localizeStrings.Get(13205); - else - strValue = m_strBackendChannels; + m_updateBackendCacheRequested = true; + strValue = m_strBackendChannels; } void CPVRGUIInfo::CharInfoBackendTimers(std::string &strValue) const { - if (m_strBackendTimers.empty()) - strValue = g_localizeStrings.Get(13205); - else - strValue = m_strBackendTimers; + m_updateBackendCacheRequested = true; + strValue = m_strBackendTimers; } void CPVRGUIInfo::CharInfoBackendRecordings(std::string &strValue) const { - if (m_strBackendRecordings.empty()) - strValue = g_localizeStrings.Get(13205); - else - strValue = m_strBackendRecordings; + m_updateBackendCacheRequested = true; + strValue = m_strBackendRecordings; } void CPVRGUIInfo::CharInfoBackendDeletedRecordings(std::string &strValue) const { - if (m_strBackendDeletedRecordings.empty()) - strValue = g_localizeStrings.Get(13205); /* Unknown */ - else - strValue = m_strBackendDeletedRecordings; + m_updateBackendCacheRequested = true; + strValue = m_strBackendDeletedRecordings; } void CPVRGUIInfo::CharInfoPlayingClientName(std::string &strValue) const @@ -753,50 +742,61 @@ void CPVRGUIInfo::UpdateBackendCache(void) { CSingleLock lock(m_critSection); - // Update the backend information for all backends once per iteration - if (m_iCurrentActiveClient == 0) + // Update the backend information for all backends if + // an update has been requested + if (m_iCurrentActiveClient == 0 && m_updateBackendCacheRequested) { std::vector<SBackend> backendProperties; { CSingleExit exit(m_critSection); backendProperties = g_PVRClients->GetBackendProperties(); } + m_backendProperties = backendProperties; + m_updateBackendCacheRequested = false; } - // Get the properties for the currently active backend - const auto &backend = GetCurrentActiveBackend(); + // Store some defaults + m_strBackendName = g_localizeStrings.Get(13205); + m_strBackendVersion = g_localizeStrings.Get(13205); + m_strBackendHost = g_localizeStrings.Get(13205); + m_strBackendChannels = g_localizeStrings.Get(13205); + m_strBackendTimers = g_localizeStrings.Get(13205); + m_strBackendRecordings = g_localizeStrings.Get(13205); + m_strBackendDeletedRecordings = g_localizeStrings.Get(13205); + m_iBackendDiskTotal = 0; + m_iBackendDiskUsed = 0; + + // Update with values from the current client when we have at least one + if (!m_backendProperties.empty()) + { + const auto &backend = m_backendProperties[m_iCurrentActiveClient]; - if (backend.numChannels >= 0) - m_strBackendChannels = StringUtils::Format("%i", backend.numChannels); - else - m_strBackendChannels = g_localizeStrings.Get(161); + m_strBackendName = backend.name; + m_strBackendVersion = backend.version; + m_strBackendHost = backend.host; - if (backend.numTimers >= 0) - m_strBackendTimers = StringUtils::Format("%i", backend.numTimers); - else - m_strBackendTimers = g_localizeStrings.Get(161); + if (backend.numChannels >= 0) + m_strBackendChannels = StringUtils::Format("%i", backend.numChannels); - if (backend.numRecordings >= 0) - m_strBackendRecordings = StringUtils::Format("%i", backend.numRecordings); - else - m_strBackendRecordings = g_localizeStrings.Get(161); + if (backend.numTimers >= 0) + m_strBackendTimers = StringUtils::Format("%i", backend.numTimers); - if (backend.numDeletedRecordings >= 0) - m_strBackendDeletedRecordings = StringUtils::Format("%i", backend.numDeletedRecordings); - else - m_strBackendDeletedRecordings = g_localizeStrings.Get(161); + if (backend.numRecordings >= 0) + m_strBackendRecordings = StringUtils::Format("%i", backend.numRecordings); + + if (backend.numDeletedRecordings >= 0) + m_strBackendDeletedRecordings = StringUtils::Format("%i", backend.numDeletedRecordings); + + m_iBackendDiskTotal = backend.diskTotal; + m_iBackendDiskUsed = backend.diskUsed; + } // Update the current active client, eventually wrapping around if (++m_iCurrentActiveClient >= m_backendProperties.size()) m_iCurrentActiveClient = 0; } -const SBackend& CPVRGUIInfo::GetCurrentActiveBackend() const -{ - return m_backendProperties[m_iCurrentActiveClient]; -} - void CPVRGUIInfo::UpdateTimersCache(void) { int iTimerAmount = g_PVRTimers->AmountActiveTimers(); diff --git a/xbmc/pvr/PVRGUIInfo.h b/xbmc/pvr/PVRGUIInfo.h index 1ed9b6717f..bc451d6dc5 100644 --- a/xbmc/pvr/PVRGUIInfo.h +++ b/xbmc/pvr/PVRGUIInfo.h @@ -26,6 +26,8 @@ #include "threads/Thread.h" #include "utils/Observer.h" +#include <atomic> + namespace EPG { class CEpgInfoTag; @@ -102,8 +104,6 @@ namespace PVR void UpdateNextTimer(void); void UpdateTimeshift(void); - const SBackend& GetCurrentActiveBackend() const; - bool TimerInfoToggle(void); void UpdateTimersToggle(void); void ToggleShowInfo(void); @@ -163,10 +163,15 @@ namespace PVR unsigned int m_iRecordingTimerAmount; unsigned int m_iCurrentActiveClient; std::string m_strPlayingClientName; + std::string m_strBackendName; + std::string m_strBackendVersion; + std::string m_strBackendHost; std::string m_strBackendTimers; std::string m_strBackendRecordings; std::string m_strBackendDeletedRecordings; std::string m_strBackendChannels; + long long m_iBackendDiskTotal; + long long m_iBackendDiskUsed; unsigned int m_iDuration; bool m_bHasNonRecordingTimers; @@ -195,5 +200,13 @@ namespace PVR std::string m_strTimeshiftPlayTime; CCriticalSection m_critSection; + + /** + * The various backend-related fields will only be updated when this + * flag is set. This is done to limit the amount of unnecessary + * backend querying when we're not displaying any of the queried + * information. + */ + mutable std::atomic<bool> m_updateBackendCacheRequested; }; } diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 866e684a47..2f5397005e 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -18,16 +18,20 @@ * */ -#include "Application.h" -#include "GUIInfoManager.h" -#include "Util.h" +#include "PVRManager.h" + +#include <cassert> +#include <utility> + #include "addons/AddonInstaller.h" -#include "epg/EpgContainer.h" -#include "dialogs/GUIDialogOK.h" -#include "dialogs/GUIDialogNumeric.h" -#include "dialogs/GUIDialogProgress.h" +#include "Application.h" #include "dialogs/GUIDialogExtendedProgressBar.h" #include "dialogs/GUIDialogKaiToast.h" +#include "dialogs/GUIDialogNumeric.h" +#include "dialogs/GUIDialogOK.h" +#include "dialogs/GUIDialogProgress.h" +#include "epg/EpgContainer.h" +#include "GUIInfoManager.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" #include "interfaces/AnnouncementManager.h" @@ -35,33 +39,29 @@ #include "messaging/helpers/DialogHelper.h" #include "music/tags/MusicInfoTag.h" #include "network/Network.h" -#include "settings/MediaSettings.h" -#include "settings/lib/Setting.h" -#include "settings/Settings.h" -#include "threads/SingleLock.h" -#include "utils/JobManager.h" -#include "utils/log.h" -#include "utils/Stopwatch.h" -#include "utils/StringUtils.h" -#include "utils/Variant.h" -#include "video/VideoDatabase.h" - -#include "pvr/PVRActionListener.h" -#include "pvr/PVRDatabase.h" -#include "pvr/PVRGUIInfo.h" #include "pvr/addons/PVRClients.h" #include "pvr/channels/PVRChannel.h" #include "pvr/channels/PVRChannelGroupInternal.h" #include "pvr/channels/PVRChannelGroupsContainer.h" #include "pvr/dialogs/GUIDialogPVRChannelManager.h" #include "pvr/dialogs/GUIDialogPVRGroupManager.h" +#include "pvr/PVRActionListener.h" +#include "pvr/PVRDatabase.h" +#include "pvr/PVRGUIInfo.h" #include "pvr/recordings/PVRRecordings.h" #include "pvr/timers/PVRTimers.h" #include "pvr/windows/GUIWindowPVRBase.h" - -#include "PVRManager.h" - -#include <assert.h> +#include "settings/lib/Setting.h" +#include "settings/MediaSettings.h" +#include "settings/Settings.h" +#include "threads/SingleLock.h" +#include "Util.h" +#include "utils/JobManager.h" +#include "utils/log.h" +#include "utils/Stopwatch.h" +#include "utils/StringUtils.h" +#include "utils/Variant.h" +#include "video/VideoDatabase.h" using namespace MUSIC_INFO; using namespace PVR; diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index da85c879ce..17e5e2c290 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -18,26 +18,26 @@ * */ +#include "PVRClients.h" + +#include <cassert> +#include <utility> + #include "Application.h" -#include "GUIUserMessages.h" #include "cores/IPlayer.h" #include "dialogs/GUIDialogExtendedProgressBar.h" #include "dialogs/GUIDialogOK.h" #include "dialogs/GUIDialogSelect.h" #include "guilib/GUIWindowManager.h" +#include "GUIUserMessages.h" #include "messaging/ApplicationMessenger.h" -#include "settings/Settings.h" -#include "utils/Variant.h" - -#include "pvr/PVRManager.h" -#include "pvr/channels/PVRChannelGroups.h" #include "pvr/channels/PVRChannelGroupInternal.h" +#include "pvr/channels/PVRChannelGroups.h" +#include "pvr/PVRManager.h" #include "pvr/recordings/PVRRecordings.h" #include "pvr/timers/PVRTimers.h" - -#include "PVRClients.h" - -#include <assert.h> +#include "settings/Settings.h" +#include "utils/Variant.h" using namespace ADDON; using namespace PVR; diff --git a/xbmc/pvr/channels/PVRChannel.h b/xbmc/pvr/channels/PVRChannel.h index f0d08cc0bd..71598571e0 100644 --- a/xbmc/pvr/channels/PVRChannel.h +++ b/xbmc/pvr/channels/PVRChannel.h @@ -19,14 +19,15 @@ * */ -#include "FileItem.h" +#include <memory> +#include <utility> + #include "addons/include/xbmc_pvr_types.h" +#include "FileItem.h" #include "threads/CriticalSection.h" #include "utils/ISerializable.h" #include "utils/Observer.h" -#include <memory> - #define PVR_INVALID_CHANNEL_UID -1 class CVariant; diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h index 2ba15828af..55b60b86f8 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.h +++ b/xbmc/pvr/channels/PVRChannelGroup.h @@ -19,14 +19,14 @@ * */ +#include <memory> +#include <utility> + #include "FileItem.h" +#include "PVRChannel.h" #include "settings/lib/ISettingCallback.h" #include "utils/JobManager.h" -#include "PVRChannel.h" - -#include <memory> - namespace EPG { struct EpgSearchFilter; diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp index 08403c206e..3cbd7caec1 100644 --- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp @@ -18,21 +18,21 @@ * */ +#include "PVRChannelGroupInternal.h" + +#include <cassert> +#include <utility> + #include "dialogs/GUIDialogOK.h" #include "epg/EpgContainer.h" -#include "settings/AdvancedSettings.h" -#include "utils/log.h" -#include "utils/Variant.h" - +#include "pvr/addons/PVRClients.h" #include "pvr/PVRDatabase.h" #include "pvr/PVRManager.h" -#include "pvr/addons/PVRClients.h" #include "pvr/timers/PVRTimers.h" - -#include "PVRChannelGroupInternal.h" #include "PVRChannelGroupsContainer.h" - -#include <assert.h> +#include "settings/AdvancedSettings.h" +#include "utils/log.h" +#include "utils/Variant.h" using namespace PVR; using namespace EPG; diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp index b4b9097919..260e9afcad 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp @@ -41,6 +41,7 @@ #include "GUIDialogPVRChannelManager.h" #include "GUIDialogPVRGroupManager.h" +#include <utility> #define BUTTON_OK 4 #define BUTTON_APPLY 5 diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp index bc4424650d..d3ab2a3569 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp @@ -18,16 +18,17 @@ * */ +#include "GUIDialogPVRGuideSearch.h" + +#include <utility> + #include "addons/include/xbmc_pvr_types.h" #include "epg/EpgSearchFilter.h" -#include "guilib/LocalizeStrings.h" #include "guilib/GUIEditControl.h" -#include "utils/StringUtils.h" - -#include "pvr/PVRManager.h" +#include "guilib/LocalizeStrings.h" #include "pvr/channels/PVRChannelGroupsContainer.h" - -#include "GUIDialogPVRGuideSearch.h" +#include "pvr/PVRManager.h" +#include "utils/StringUtils.h" using namespace PVR; diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp index 86b0136489..f0879ff105 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp @@ -18,26 +18,25 @@ * */ -#include "FileItem.h" +#include "GUIDialogPVRTimerSettings.h" + #include "addons/include/xbmc_pvr_types.h" #include "dialogs/GUIDialogNumeric.h" +#include "FileItem.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" -#include "settings/SettingUtils.h" +#include "pvr/addons/PVRClient.h" +#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/PVRManager.h" +#include "pvr/timers/PVRTimerInfoTag.h" +#include "pvr/timers/PVRTimerType.h" #include "settings/lib/Setting.h" #include "settings/lib/SettingsManager.h" +#include "settings/SettingUtils.h" #include "settings/windows/GUIControlSettings.h" #include "utils/log.h" #include "utils/StringUtils.h" -#include "pvr/PVRManager.h" -#include "pvr/addons/PVRClient.h" -#include "pvr/channels/PVRChannelGroupsContainer.h" -#include "pvr/timers/PVRTimerInfoTag.h" -#include "pvr/timers/PVRTimerType.h" - -#include "GUIDialogPVRTimerSettings.h" - using namespace PVR; #define SETTING_TMR_TYPE "timer.type" @@ -737,6 +736,10 @@ void CGUIDialogPVRTimerSettings::InitializeTypesList() if (type->RequiresEpgTagOnCreate() && !m_timerInfoTag->HasEpgInfoTag()) continue; + // Drop TimerTypes without 'Series' EPG attributes if none are set + if (type->RequiresEpgSeriesOnCreate() && !m_timerInfoTag->HasSeriesEpgInfoTag()) + continue; + // Drop TimerTypes that forbid EPGInfo, if it is populated if (type->ForbidsEpgTagOnCreate() && m_timerInfoTag->HasEpgInfoTag()) continue; diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h index 324ec39c02..f2eb320968 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h +++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h @@ -22,9 +22,10 @@ #include "pvr/channels/PVRChannel.h" // PVR_INVALID_CHANNEL_UID #include "settings/dialogs/GUIDialogSettingsManualBase.h" +#include <map> #include <memory> +#include <utility> #include <vector> -#include <map> class CFileItem; class CSetting; diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 663096ddc8..5288a34808 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -18,19 +18,20 @@ * */ -#include "FileItem.h" +#include "PVRRecordings.h" + +#include <utility> + #include "epg/EpgContainer.h" +#include "FileItem.h" +#include "pvr/addons/PVRClients.h" +#include "pvr/PVRManager.h" #include "threads/SingleLock.h" #include "utils/log.h" -#include "utils/URIUtils.h" #include "utils/StringUtils.h" +#include "utils/URIUtils.h" #include "video/VideoDatabase.h" -#include "pvr/PVRManager.h" -#include "pvr/addons/PVRClients.h" - -#include "PVRRecordings.h" - using namespace PVR; CPVRRecordings::CPVRRecordings(void) : diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.cpp b/xbmc/pvr/timers/PVRTimerInfoTag.cpp index a238736932..ba3b1dd9f3 100644 --- a/xbmc/pvr/timers/PVRTimerInfoTag.cpp +++ b/xbmc/pvr/timers/PVRTimerInfoTag.cpp @@ -879,6 +879,18 @@ bool CPVRTimerInfoTag::HasEpgInfoTag(void) const return m_epgTag != NULL; } +bool CPVRTimerInfoTag::HasSeriesEpgInfoTag(void) const +{ + if (m_epgTag && + (m_epgTag->IsSeries() || + m_epgTag->SeriesNumber() > 0 || + m_epgTag->EpisodeNumber() > 0 || + m_epgTag->EpisodePart() > 0)) + return true; + else + return false; +} + void CPVRTimerInfoTag::ClearEpgTag(void) { CEpgInfoTagPtr deletedTag; diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.h b/xbmc/pvr/timers/PVRTimerInfoTag.h index a4d6dea8d9..7a09a738f5 100644 --- a/xbmc/pvr/timers/PVRTimerInfoTag.h +++ b/xbmc/pvr/timers/PVRTimerInfoTag.h @@ -37,12 +37,13 @@ * number of the tag reported by the PVR backend and can not be played! */ -#include "XBDateTime.h" +#include <memory> + #include "addons/include/xbmc_pvr_types.h" -#include "utils/ISerializable.h" #include "pvr/timers/PVRTimerType.h" - -#include <memory> +#include "threads/CriticalSection.h" +#include "utils/ISerializable.h" +#include "XBDateTime.h" class CFileItem; class CVariant; @@ -103,6 +104,11 @@ namespace PVR */ bool HasEpgInfoTag() const; + /*! + * @return True if this timer has corresponding epg info tag with series attributes, false otherwise + */ + bool HasSeriesEpgInfoTag() const; + int ChannelNumber(void) const; std::string ChannelName(void) const; std::string ChannelIcon(void) const; diff --git a/xbmc/pvr/timers/PVRTimerType.h b/xbmc/pvr/timers/PVRTimerType.h index c8d91dc361..cbc01a9445 100644 --- a/xbmc/pvr/timers/PVRTimerType.h +++ b/xbmc/pvr/timers/PVRTimerType.h @@ -20,8 +20,9 @@ */ #include <memory> -#include <vector> #include <string> +#include <utility> +#include <vector> struct PVR_TIMER_TYPE; @@ -162,7 +163,14 @@ namespace PVR * @brief Check whether this timer type requires epg tag info to be present. * @return True if new instances require EPG info, false otherwise. */ - bool RequiresEpgTagOnCreate() const { return (m_iAttributes & PVR_TIMER_TYPE_REQUIRES_EPG_TAG_ON_CREATE) > 0; } + bool RequiresEpgTagOnCreate() const { return (m_iAttributes & (PVR_TIMER_TYPE_REQUIRES_EPG_TAG_ON_CREATE | + PVR_TIMER_TYPE_REQUIRES_EPG_SERIES_ON_CREATE)) > 0; } + + /*! + * @brief Check whether this timer type requires epg tag info including series attributes to be present. + * @return True if new instances require an EPG tag with series attributes, false otherwise. + */ + bool RequiresEpgSeriesOnCreate() const { return (m_iAttributes & PVR_TIMER_TYPE_REQUIRES_EPG_SERIES_ON_CREATE) > 0; } /*! * @brief Check whether this type supports the "enabling/disabling" of timers of its type. diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp index 19853b8b81..43d01e5c63 100644 --- a/xbmc/pvr/timers/PVRTimers.cpp +++ b/xbmc/pvr/timers/PVRTimers.cpp @@ -18,25 +18,25 @@ * */ -#include "FileItem.h" +#include "PVRTimers.h" + +#include <cassert> +#include <cstdlib> +#include <utility> + #include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogOK.h" #include "epg/EpgContainer.h" +#include "FileItem.h" +#include "pvr/addons/PVRClients.h" +#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/PVRManager.h" #include "settings/Settings.h" #include "threads/SingleLock.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/Variant.h" -#include "pvr/PVRManager.h" -#include "pvr/addons/PVRClients.h" -#include "pvr/channels/PVRChannelGroupsContainer.h" - -#include "PVRTimers.h" - -#include <assert.h> -#include <cstdlib> - using namespace PVR; using namespace EPG; @@ -647,7 +647,7 @@ CPVRTimerInfoTagPtr CPVRTimers::GetByClient(int iClientId, unsigned int iClientT for (VecTimerInfoTag::const_iterator timerIt = it->second->begin(); timerIt != it->second->end(); ++timerIt) { if ((*timerIt)->m_iClientId == iClientId && - (*timerIt)->m_iClientIndex == static_cast<int>(iClientTimerId)) + (*timerIt)->m_iClientIndex == iClientTimerId) return *timerIt; } } diff --git a/xbmc/pvr/timers/PVRTimers.h b/xbmc/pvr/timers/PVRTimers.h index 8293ba98b5..7ba84183ee 100644 --- a/xbmc/pvr/timers/PVRTimers.h +++ b/xbmc/pvr/timers/PVRTimers.h @@ -19,13 +19,18 @@ * */ -#include "XBDateTime.h" -#include "addons/include/xbmc_pvr_types.h" -#include "utils/Observer.h" +#include <map> +#include <memory> +#include "addons/include/xbmc_pvr_types.h" #include "PVRTimerInfoTag.h" +#include "utils/Observer.h" +#include "XBDateTime.h" class CFileItem; +class CFileItemList; +typedef std::shared_ptr<CFileItem> CFileItemPtr; + namespace EPG { class CEpgInfoTag; diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp index cb11fe2354..a432045b4b 100644 --- a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp @@ -121,15 +121,21 @@ bool CGUIWindowPVRSearch::OnContextButton(const CFileItem &item, CONTEXT_BUTTON m_searchfilter.m_strSearchTerm = "\"" + item.GetEPGInfoTag()->Title() + "\""; else if (item.IsPVRChannel()) { - CEpgInfoTagPtr tag(item.GetPVRChannelInfoTag()->GetEPGNow()); + const CEpgInfoTagPtr tag(item.GetPVRChannelInfoTag()->GetEPGNow()); if (tag) m_searchfilter.m_strSearchTerm = "\"" + tag->Title() + "\""; } else if (item.IsUsablePVRRecording()) m_searchfilter.m_strSearchTerm = "\"" + item.GetPVRRecordingInfoTag()->m_strTitle + "\""; else if (item.IsPVRTimer()) - m_searchfilter.m_strSearchTerm = "\"" + item.GetPVRTimerInfoTag()->m_strTitle + "\""; - + { + const CPVRTimerInfoTagPtr info(item.GetPVRTimerInfoTag()); + const CEpgInfoTagPtr tag(info->GetEpgInfoTag()); + if (tag) + m_searchfilter.m_strSearchTerm = "\"" + tag->Title() + "\""; + else + m_searchfilter.m_strSearchTerm = "\"" + info->m_strTitle + "\""; + } m_bSearchConfirmed = true; Refresh(true); bReturn = true; @@ -144,20 +150,19 @@ bool CGUIWindowPVRSearch::OnContextButton(const CFileItem &item, CONTEXT_BUTTON void CGUIWindowPVRSearch::OnPrepareFileItems(CFileItemList &items) { - items.Clear(); - - CFileItemPtr item(new CFileItem("pvr://guide/searchresults/search/", true)); - item->SetLabel(g_localizeStrings.Get(19140)); - item->SetLabelPreformated(true); - item->SetSpecialSort(SortSpecialOnTop); - items.Add(item); + bool bAddSpecialSearchItem = items.IsEmpty(); if (m_bSearchConfirmed) { + m_bSearchConfirmed = false; + + items.Clear(); + bAddSpecialSearchItem = true; + CGUIDialogProgress* dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); if (dlgProgress) { - dlgProgress->SetHeading(CVariant{194}); + dlgProgress->SetHeading(CVariant{194}); // "Searching..." dlgProgress->SetText(CVariant{m_searchfilter.m_strSearchTerm}); dlgProgress->Open(); dlgProgress->Progress(); @@ -170,10 +175,17 @@ void CGUIWindowPVRSearch::OnPrepareFileItems(CFileItemList &items) dlgProgress->Close(); if (items.IsEmpty()) - { - CGUIDialogOK::ShowAndGetInput(CVariant{194}, CVariant{284}); - m_bSearchConfirmed = false; - } + CGUIDialogOK::ShowAndGetInput(CVariant{194}, // "Searching..." + CVariant{284}); // "No results found" + } + + if (bAddSpecialSearchItem) + { + CFileItemPtr item(new CFileItem("pvr://guide/searchresults/search/", true)); + item->SetLabel(g_localizeStrings.Get(19140)); // "Search..." + item->SetLabelPreformated(true); + item->SetSpecialSort(SortSpecialOnTop); + items.Add(item); } } diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index d63e326953..5c8cd7e829 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -18,34 +18,34 @@ * */ +#include "AdvancedSettings.h" + +#include <climits> #include <algorithm> #include <string> #include <vector> -#include <utility> - -#include <limits.h> -#include "system.h" -#include "AdvancedSettings.h" +#include "addons/AddonManager.h" +#include "addons/AudioDecoder.h" +#include "addons/IAddon.h" #include "Application.h" -#include "network/DNSNameCache.h" #include "filesystem/File.h" -#include "utils/LangCodeExpander.h" +#include "filesystem/SpecialProtocol.h" #include "LangInfo.h" +#include "network/DNSNameCache.h" #include "profiles/ProfilesManager.h" #include "settings/lib/Setting.h" #include "settings/Settings.h" #include "settings/SettingUtils.h" +#include "system.h" +#include "utils/LangCodeExpander.h" +#include "utils/log.h" #include "utils/StringUtils.h" #include "utils/SystemInfo.h" #include "utils/URIUtils.h" -#include "utils/XMLUtils.h" -#include "utils/log.h" #include "utils/Variant.h" -#include "filesystem/SpecialProtocol.h" -#include "addons/IAddon.h" -#include "addons/AddonManager.h" -#include "addons/AudioDecoder.h" +#include "utils/XMLUtils.h" + #if defined(TARGET_DARWIN_IOS) #include "osx/DarwinUtils.h" #endif diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h index 8ec91c395f..7c3759d27a 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -21,6 +21,7 @@ #include <set> #include <string> +#include <utility> #include <vector> #include "pictures/PictureScalingAlgorithm.h" diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp index 12c4859e3e..7993a732c2 100644 --- a/xbmc/settings/DisplaySettings.cpp +++ b/xbmc/settings/DisplaySettings.cpp @@ -18,15 +18,15 @@ * */ -#include <algorithm> +#include "DisplaySettings.h" + #include <cstdlib> +#include <float.h> +#include <algorithm> #include <string> #include <utility> #include <vector> -#include <float.h> - -#include "DisplaySettings.h" #include "guilib/GraphicContext.h" #include "guilib/gui3d.h" #include "guilib/LocalizeStrings.h" diff --git a/xbmc/settings/DisplaySettings.h b/xbmc/settings/DisplaySettings.h index cceb554bb1..8402340f4c 100644 --- a/xbmc/settings/DisplaySettings.h +++ b/xbmc/settings/DisplaySettings.h @@ -21,6 +21,7 @@ #include <map> #include <set> +#include <utility> #include <vector> #include "guilib/Resolution.h" diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp index 2f31f6280d..41927739ed 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -136,6 +136,7 @@ const std::string CSettings::SETTING_VIDEOLIBRARY_TVSHOWSSELECTFIRSTUNWATCHEDITE const std::string CSettings::SETTING_VIDEOLIBRARY_TVSHOWSINCLUDEALLSEASONSANDSPECIALS = "videolibrary.tvshowsincludeallseasonsandspecials"; const std::string CSettings::SETTING_VIDEOLIBRARY_SHOWALLITEMS = "videolibrary.showallitems"; const std::string CSettings::SETTING_VIDEOLIBRARY_GROUPMOVIESETS = "videolibrary.groupmoviesets"; +const std::string CSettings::SETTING_VIDEOLIBRARY_GROUPSINGLEITEMSETS = "videolibrary.groupsingleitemsets"; const std::string CSettings::SETTING_VIDEOLIBRARY_UPDATEONSTARTUP = "videolibrary.updateonstartup"; const std::string CSettings::SETTING_VIDEOLIBRARY_BACKGROUNDUPDATE = "videolibrary.backgroundupdate"; const std::string CSettings::SETTING_VIDEOLIBRARY_CLEANUP = "videolibrary.cleanup"; diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h index 9150f884da..aa1cbaf045 100644 --- a/xbmc/settings/Settings.h +++ b/xbmc/settings/Settings.h @@ -93,6 +93,7 @@ public: static const std::string SETTING_VIDEOLIBRARY_TVSHOWSINCLUDEALLSEASONSANDSPECIALS; static const std::string SETTING_VIDEOLIBRARY_SHOWALLITEMS; static const std::string SETTING_VIDEOLIBRARY_GROUPMOVIESETS; + static const std::string SETTING_VIDEOLIBRARY_GROUPSINGLEITEMSETS; static const std::string SETTING_VIDEOLIBRARY_UPDATEONSTARTUP; static const std::string SETTING_VIDEOLIBRARY_BACKGROUNDUPDATE; static const std::string SETTING_VIDEOLIBRARY_CLEANUP; diff --git a/xbmc/settings/dialogs/GUIDialogAudioDSPSettings.h b/xbmc/settings/dialogs/GUIDialogAudioDSPSettings.h index a488f302ec..c573098a65 100644 --- a/xbmc/settings/dialogs/GUIDialogAudioDSPSettings.h +++ b/xbmc/settings/dialogs/GUIDialogAudioDSPSettings.h @@ -19,6 +19,8 @@ * */ +#include <utility> + #include "cores/AudioEngine/DSPAddons/ActiveAEDSPProcess.h" #include "settings/dialogs/GUIDialogSettingsManualBase.h" diff --git a/xbmc/settings/lib/SettingConditions.h b/xbmc/settings/lib/SettingConditions.h index f8754c45ef..112df5b74c 100644 --- a/xbmc/settings/lib/SettingConditions.h +++ b/xbmc/settings/lib/SettingConditions.h @@ -22,6 +22,7 @@ #include <map> #include <set> #include <string> +#include <utility> #include "SettingDefinitions.h" #include "utils/BooleanLogic.h" diff --git a/xbmc/settings/lib/SettingDefinitions.h b/xbmc/settings/lib/SettingDefinitions.h index d497f04f30..3b4829d429 100644 --- a/xbmc/settings/lib/SettingDefinitions.h +++ b/xbmc/settings/lib/SettingDefinitions.h @@ -20,6 +20,7 @@ */ #include <string> +#include <utility> #include <vector> #define SETTING_XML_ROOT "settings" diff --git a/xbmc/settings/lib/SettingsManager.cpp b/xbmc/settings/lib/SettingsManager.cpp index 505f1b7530..ddc63384f2 100644 --- a/xbmc/settings/lib/SettingsManager.cpp +++ b/xbmc/settings/lib/SettingsManager.cpp @@ -19,6 +19,10 @@ */ #include "SettingsManager.h" + +#include <algorithm> +#include <utility> + #include "SettingDefinitions.h" #include "SettingSection.h" #include "Setting.h" @@ -26,8 +30,6 @@ #include "utils/StringUtils.h" #include "utils/XBMCTinyXML.h" -#include <algorithm> - CSettingsManager::CSettingsManager() : m_initialized(false), m_loaded(false) { } diff --git a/xbmc/settings/windows/GUIControlSettings.cpp b/xbmc/settings/windows/GUIControlSettings.cpp index bb335b14b6..fa6e633bd0 100644 --- a/xbmc/settings/windows/GUIControlSettings.cpp +++ b/xbmc/settings/windows/GUIControlSettings.cpp @@ -18,17 +18,18 @@ * */ +#include "GUIControlSettings.h" + #include <set> +#include <utility> -#include "GUIControlSettings.h" -#include "FileItem.h" -#include "Util.h" #include "addons/AddonManager.h" #include "addons/GUIWindowAddonBrowser.h" #include "dialogs/GUIDialogFileBrowser.h" #include "dialogs/GUIDialogOK.h" #include "dialogs/GUIDialogSelect.h" #include "dialogs/GUIDialogSlider.h" +#include "FileItem.h" #include "guilib/GUIEditControl.h" #include "guilib/GUIImage.h" #include "guilib/GUILabelControl.h" @@ -37,13 +38,14 @@ #include "guilib/GUISpinControlEx.h" #include "guilib/GUIWindowManager.h" #include "guilib/LocalizeStrings.h" +#include "settings/lib/Setting.h" +#include "settings/MediaSourceSettings.h" #include "settings/SettingAddon.h" #include "settings/SettingControl.h" #include "settings/SettingPath.h" #include "settings/SettingUtils.h" -#include "settings/MediaSourceSettings.h" -#include "settings/lib/Setting.h" #include "storage/MediaManager.h" +#include "Util.h" #include "utils/StringUtils.h" #include "utils/Variant.h" diff --git a/xbmc/settings/windows/GUIWindowSettingsScreenCalibration.cpp b/xbmc/settings/windows/GUIWindowSettingsScreenCalibration.cpp index 34e99faff1..e25d332a82 100644 --- a/xbmc/settings/windows/GUIWindowSettingsScreenCalibration.cpp +++ b/xbmc/settings/windows/GUIWindowSettingsScreenCalibration.cpp @@ -142,7 +142,6 @@ bool CGUIWindowSettingsScreenCalibration::OnMessage(CGUIMessage& message) CDisplaySettings::GetInstance().UpdateCalibrations(); CSettings::GetInstance().Save(); g_graphicsContext.SetCalibrating(false); - g_windowManager.ShowOverlay(OVERLAY_STATE_SHOWN); // reset our screen resolution to what it was initially g_graphicsContext.SetVideoResolution(CDisplaySettings::GetInstance().GetCurrentResolution()); // Inform the player so we can update the resolution @@ -156,7 +155,6 @@ bool CGUIWindowSettingsScreenCalibration::OnMessage(CGUIMessage& message) case GUI_MSG_WINDOW_INIT: { CGUIWindow::OnMessage(message); - g_windowManager.ShowOverlay(OVERLAY_STATE_HIDDEN); g_graphicsContext.SetCalibrating(true); // Get the allowable resolutions that we can calibrate... diff --git a/xbmc/utils/AlarmClock.cpp b/xbmc/utils/AlarmClock.cpp index 8ef7a685d0..065673604a 100644 --- a/xbmc/utils/AlarmClock.cpp +++ b/xbmc/utils/AlarmClock.cpp @@ -19,13 +19,16 @@ */ #include "AlarmClock.h" + +#include <utility> + +#include "dialogs/GUIDialogKaiToast.h" #include "events/EventLog.h" #include "events/NotificationEvent.h" -#include "messaging/ApplicationMessenger.h" #include "guilib/LocalizeStrings.h" -#include "threads/SingleLock.h" #include "log.h" -#include "dialogs/GUIDialogKaiToast.h" +#include "messaging/ApplicationMessenger.h" +#include "threads/SingleLock.h" #include "utils/StringUtils.h" using namespace KODI::MESSAGING; diff --git a/xbmc/utils/AutoPtrHandle.cpp b/xbmc/utils/AutoPtrHandle.cpp deleted file mode 100644 index 1b82d9e249..0000000000 --- a/xbmc/utils/AutoPtrHandle.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "AutoPtrHandle.h" - -using namespace AUTOPTR; - -CAutoPtrHandle::CAutoPtrHandle(HANDLE hHandle) - : m_hHandle(hHandle) -{} - -CAutoPtrHandle::~CAutoPtrHandle(void) -{ - Cleanup(); -} - -CAutoPtrHandle::operator HANDLE() -{ - return m_hHandle; -} - -void CAutoPtrHandle::attach(HANDLE hHandle) -{ - Cleanup(); - m_hHandle = hHandle; -} - -HANDLE CAutoPtrHandle::release() -{ - HANDLE hTmp = m_hHandle; - m_hHandle = INVALID_HANDLE_VALUE; - return hTmp; -} - -void CAutoPtrHandle::Cleanup() -{ - if ( isValid() ) - { - CloseHandle(m_hHandle); - m_hHandle = INVALID_HANDLE_VALUE; - } -} - -bool CAutoPtrHandle::isValid() const -{ - if ( INVALID_HANDLE_VALUE != m_hHandle) - return true; - return false; -} -void CAutoPtrHandle::reset() -{ - Cleanup(); -} - -//------------------------------------------------------------------------------- -CAutoPtrFind ::CAutoPtrFind(HANDLE hHandle) - : CAutoPtrHandle(hHandle) -{} -CAutoPtrFind::~CAutoPtrFind(void) -{ - Cleanup(); -} - -void CAutoPtrFind::Cleanup() -{ - if ( isValid() ) - { - FindClose(m_hHandle); - m_hHandle = INVALID_HANDLE_VALUE; - } -} - -//------------------------------------------------------------------------------- -CAutoPtrSocket::CAutoPtrSocket(SOCKET hSocket) - : m_hSocket(hSocket) -{} - -CAutoPtrSocket::~CAutoPtrSocket(void) -{ - Cleanup(); -} - -CAutoPtrSocket::operator SOCKET() -{ - return m_hSocket; -} - -void CAutoPtrSocket::attach(SOCKET hSocket) -{ - Cleanup(); - m_hSocket = hSocket; -} - -SOCKET CAutoPtrSocket::release() -{ - SOCKET hTmp = m_hSocket; - m_hSocket = INVALID_SOCKET; - return hTmp; -} - -void CAutoPtrSocket::Cleanup() -{ - if ( isValid() ) - { - closesocket(m_hSocket); - m_hSocket = INVALID_SOCKET; - } -} - -bool CAutoPtrSocket::isValid() const -{ - if ( INVALID_SOCKET != m_hSocket) - return true; - return false; -} -void CAutoPtrSocket::reset() -{ - Cleanup(); -} diff --git a/xbmc/utils/AutoPtrHandle.h b/xbmc/utils/AutoPtrHandle.h deleted file mode 100644 index 945e59cc78..0000000000 --- a/xbmc/utils/AutoPtrHandle.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "system.h" // for HANDLE and SOCKET -#include <stdlib.h> - -namespace AUTOPTR -{ -class CAutoPtrHandle -{ -public: - CAutoPtrHandle(HANDLE hHandle); - virtual ~CAutoPtrHandle(void); - operator HANDLE(); - void attach(HANDLE hHandle); - HANDLE release(); - bool isValid() const; - void reset(); -protected: - virtual void Cleanup(); - HANDLE m_hHandle; -}; - -class CAutoPtrFind : public CAutoPtrHandle -{ -public: - CAutoPtrFind(HANDLE hHandle); - virtual ~CAutoPtrFind(void); -protected: - virtual void Cleanup(); -}; - - -class CAutoPtrSocket -{ -public: - CAutoPtrSocket(SOCKET hSocket); - virtual ~CAutoPtrSocket(void); - operator SOCKET(); - void attach(SOCKET hSocket); - SOCKET release(); - bool isValid() const; - void reset(); -protected: - virtual void Cleanup(); - SOCKET m_hSocket; -}; - -} diff --git a/xbmc/utils/CharsetConverter.cpp b/xbmc/utils/CharsetConverter.cpp index 6fed5b6772..b56760ca08 100644 --- a/xbmc/utils/CharsetConverter.cpp +++ b/xbmc/utils/CharsetConverter.cpp @@ -19,19 +19,22 @@ */ #include "CharsetConverter.h" -#include "utils/StringUtils.h" + +#include <cerrno> +#include <algorithm> + +#include <iconv.h> #include <fribidi/fribidi.h> -#include "LangInfo.h" + #include "guilib/LocalizeStrings.h" +#include "LangInfo.h" +#include "log.h" #include "settings/lib/Setting.h" #include "settings/Settings.h" +#include "system.h" #include "threads/SingleLock.h" +#include "utils/StringUtils.h" #include "utils/Utf8Utils.h" -#include "log.h" - -#include <errno.h> -#include <iconv.h> -#include <algorithm> #if !defined(TARGET_WINDOWS) && defined(HAVE_CONFIG_H) #include "config.h" diff --git a/xbmc/utils/CharsetConverter.h b/xbmc/utils/CharsetConverter.h index a403286f62..91c2a76aea 100644 --- a/xbmc/utils/CharsetConverter.h +++ b/xbmc/utils/CharsetConverter.h @@ -21,13 +21,14 @@ * */ +#include <string> +#include <utility> +#include <vector> + #include "settings/lib/ISettingCallback.h" #include "utils/GlobalsHandling.h" #include "utils/uXstrings.h" -#include <string> -#include <vector> - class CSetting; class CCharsetConverter : public ISettingCallback diff --git a/xbmc/utils/GroupUtils.cpp b/xbmc/utils/GroupUtils.cpp index 88862bbfad..e9f80dc4be 100644 --- a/xbmc/utils/GroupUtils.cpp +++ b/xbmc/utils/GroupUtils.cpp @@ -18,21 +18,28 @@ * */ +#include "GroupUtils.h" + #include <map> #include <set> -#include "GroupUtils.h" #include "FileItem.h" +#include "filesystem/MultiPathDirectory.h" #include "utils/StringUtils.h" +#include "utils/URIUtils.h" #include "video/VideoDbUrl.h" #include "video/VideoInfoTag.h" -#include "utils/URIUtils.h" -#include "filesystem/MultiPathDirectory.h" -typedef std::map<int, std::set<CFileItemPtr> > SetMap; +using SetMap = std::map<int, std::set<CFileItemPtr> >; bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItems, GroupAttribute groupAttributes /* = GroupAttributeNone */) { + CFileItemList ungroupedItems; + return Group(groupBy, baseDir, items, groupedItems, ungroupedItems, groupAttributes); +} + +bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItems, CFileItemList &ungroupedItems, GroupAttribute groupAttributes /* = GroupAttributeNone */) +{ if (groupBy == GroupByNone) return false; @@ -43,19 +50,19 @@ bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileI SetMap setMap; for (int index = 0; index < items.Size(); index++) { - bool add = true; + bool ungrouped = true; const CFileItemPtr item = items.Get(index); // group by sets if ((groupBy & GroupBySet) && - item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iSetId > 0) + item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iSetId > 0) { - add = false; + ungrouped = false; setMap[item->GetVideoInfoTag()->m_iSetId].insert(item); } - if (add) - groupedItems.Add(item); + if (ungrouped) + ungroupedItems.Add(item); } if ((groupBy & GroupBySet) && !setMap.empty()) @@ -66,10 +73,10 @@ bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileI for (SetMap::const_iterator set = setMap.begin(); set != setMap.end(); ++set) { - // only one item in the set, so just re-add it + // only one item in the set, so add it to the ungrouped items if (set->second.size() == 1 && (groupAttributes & GroupAttributeIgnoreSingleItems)) { - groupedItems.Add(*set->second.begin()); + ungroupedItems.Add(*set->second.begin()); continue; } @@ -91,6 +98,7 @@ bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileI CVideoInfoTag* setInfo = pItem->GetVideoInfoTag(); setInfo->m_strPath = pItem->GetPath(); setInfo->m_strTitle = pItem->GetLabel(); + setInfo->m_strPlot = (*set->second.begin())->GetVideoInfoTag()->m_strSetOverview; int ratings = 0; int iWatched = 0; // have all the movies been played at least once? @@ -104,19 +112,19 @@ bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileI ratings++; setInfo->m_fRating += movieInfo->m_fRating; } - + // handle year if (movieInfo->m_iYear > setInfo->m_iYear) setInfo->m_iYear = movieInfo->m_iYear; - + // handle lastplayed if (movieInfo->m_lastPlayed.IsValid() && movieInfo->m_lastPlayed > setInfo->m_lastPlayed) setInfo->m_lastPlayed = movieInfo->m_lastPlayed; - + // handle dateadded if (movieInfo->m_dateAdded.IsValid() && movieInfo->m_dateAdded > setInfo->m_dateAdded) setInfo->m_dateAdded = movieInfo->m_dateAdded; - + // handle playcount/watched setInfo->m_playCount += movieInfo->m_playCount; if (movieInfo->m_playCount > 0) @@ -133,7 +141,7 @@ bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileI if (ratings > 1) pItem->GetVideoInfoTag()->m_fRating /= ratings; - + setInfo->m_playCount = iWatched >= (int)set->second.size() ? (setInfo->m_playCount / set->second.size()) : 0; pItem->SetProperty("total", (int)set->second.size()); pItem->SetProperty("watched", iWatched); @@ -147,11 +155,14 @@ bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileI return true; } -bool GroupUtils::GroupAndSort(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, const SortDescription &sortDescription, CFileItemList &groupedItems, GroupAttribute groupAttributes /* = GroupAttributeNone */) +bool GroupUtils::GroupAndMix(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItemsMixed, GroupAttribute groupAttributes /* = GroupAttributeNone */) { - if (!Group(groupBy, baseDir, items, groupedItems, groupAttributes)) + CFileItemList ungroupedItems; + if (!Group(groupBy, baseDir, items, groupedItemsMixed, ungroupedItems, groupAttributes)) return false; - groupedItems.Sort(sortDescription); + // add all the ungrouped items as well + groupedItemsMixed.Append(ungroupedItems); + return true; } diff --git a/xbmc/utils/GroupUtils.h b/xbmc/utils/GroupUtils.h index 59e73642d1..a7017c6d0d 100644 --- a/xbmc/utils/GroupUtils.h +++ b/xbmc/utils/GroupUtils.h @@ -38,5 +38,6 @@ class GroupUtils { public: static bool Group(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItems, GroupAttribute groupAttributes = GroupAttributeNone); - static bool GroupAndSort(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, const SortDescription &sortDescription, CFileItemList &groupedItems, GroupAttribute groupAttributes = GroupAttributeNone); + static bool Group(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItems, CFileItemList &ungroupedItems, GroupAttribute groupAttributes = GroupAttributeNone); + static bool GroupAndMix(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItemsMixed, GroupAttribute groupAttributes = GroupAttributeNone); }; diff --git a/xbmc/utils/HttpResponse.h b/xbmc/utils/HttpResponse.h index a2705b7b1e..3898d7f2fc 100644 --- a/xbmc/utils/HttpResponse.h +++ b/xbmc/utils/HttpResponse.h @@ -19,9 +19,10 @@ * */ +#include <map> #include <string> +#include <utility> #include <vector> -#include <map> namespace HTTP { diff --git a/xbmc/utils/Makefile.in b/xbmc/utils/Makefile.in index dbd3db9ccf..7501a7c34b 100644 --- a/xbmc/utils/Makefile.in +++ b/xbmc/utils/Makefile.in @@ -2,7 +2,6 @@ SRCS += AlarmClock.cpp SRCS += AliasShortcutUtils.cpp SRCS += Archive.cpp SRCS += AsyncFileCopy.cpp -SRCS += AutoPtrHandle.cpp SRCS += auto_buffer.cpp SRCS += Base64.cpp SRCS += BitstreamConverter.cpp diff --git a/xbmc/utils/RssManager.cpp b/xbmc/utils/RssManager.cpp index ec7a0d4444..0c1212337d 100644 --- a/xbmc/utils/RssManager.cpp +++ b/xbmc/utils/RssManager.cpp @@ -19,6 +19,9 @@ */ #include "RssManager.h" + +#include <utility> + #include "addons/AddonInstaller.h" #include "addons/AddonManager.h" #include "filesystem/File.h" diff --git a/xbmc/utils/ScopeGuard.h b/xbmc/utils/ScopeGuard.h new file mode 100644 index 0000000000..510165d9a4 --- /dev/null +++ b/xbmc/utils/ScopeGuard.h @@ -0,0 +1,109 @@ +#pragma once + +/* + * Copyright (C) 2005-2015 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <functional> + +namespace KODI +{ +namespace UTILS +{ + +/*! \class CScopeGuard + \brief Generic scopeguard designed to handle any type of handle + + This is not necessary but recommended to cut down on some typing + using CSocketHandle = CScopeGuard<SOCKET, INVALID_SOCKET, closesocket>; + + CSocketHandle sh(closesocket, open(thingy)); + */ +template<typename Handle, Handle invalid, typename Deleter> +class CScopeGuard +{ + +public: + + CScopeGuard(std::function<Deleter> del, Handle handle = invalid) + : m_handle{handle} + , m_deleter{del} + { }; + + ~CScopeGuard() + { + reset(); + } + + operator Handle() + { + return m_handle; + } + + operator bool() + { + return m_handle != invalid; + } + + /*! \brief attach a new handle to this instance, if there's + already a handle it will be closed. + + \param[in] handle The handle to manage + */ + void attach(Handle handle) + { + reset(); + + m_handle = handle; + } + + /*! \brief release the managed handle so that it won't be auto closed + + \return The handle being managed by the guard + */ + Handle release() + { + Handle h = m_handle; + m_handle = invalid; + return h; + } + + /*! \brief reset the instance, closing any managed handle and setting it to invalid + */ + void reset() + { + if (m_handle != invalid) + { + m_deleter(m_handle); + m_handle = invalid; + } + } + + //Disallow default construction and copying + CScopeGuard() = delete; + CScopeGuard(const CScopeGuard& rhs) = delete; + CScopeGuard& operator= (const CScopeGuard& rhs) = delete; + +private: + Handle m_handle; + std::function<Deleter> m_deleter; +}; + +} +}
\ No newline at end of file diff --git a/xbmc/utils/SeekHandler.cpp b/xbmc/utils/SeekHandler.cpp index bafa0d3fbc..7db32d3e74 100644 --- a/xbmc/utils/SeekHandler.cpp +++ b/xbmc/utils/SeekHandler.cpp @@ -21,13 +21,14 @@ #include "SeekHandler.h" #include <stdlib.h> -#include "guilib/LocalizeStrings.h" -#include "guilib/GraphicContext.h" + #include "Application.h" #include "FileItem.h" +#include "guilib/GraphicContext.h" +#include "guilib/LocalizeStrings.h" #include "settings/AdvancedSettings.h" -#include "settings/Settings.h" #include "settings/lib/Setting.h" +#include "settings/Settings.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/Variant.h" diff --git a/xbmc/utils/SeekHandler.h b/xbmc/utils/SeekHandler.h index a2efa88346..953a0a180a 100644 --- a/xbmc/utils/SeekHandler.h +++ b/xbmc/utils/SeekHandler.h @@ -19,16 +19,16 @@ * */ +#include <map> +#include <utility> #include <vector> + #include "input/Key.h" #include "interfaces/IActionListener.h" #include "settings/lib/ISettingCallback.h" #include "threads/CriticalSection.h" #include "utils/Stopwatch.h" -#include <map> -#include <vector> - enum SeekType { SEEK_TYPE_VIDEO = 0, diff --git a/xbmc/utils/Variant.cpp b/xbmc/utils/Variant.cpp index 3656ca4362..a7f0b83c13 100644 --- a/xbmc/utils/Variant.cpp +++ b/xbmc/utils/Variant.cpp @@ -582,7 +582,7 @@ CVariant &CVariant::operator=(const CVariant &rhs) m_data.integer = rhs.m_data.integer; break; case VariantTypeUnsignedInteger: - m_data.integer = rhs.m_data.unsignedinteger; + m_data.unsignedinteger = rhs.m_data.unsignedinteger; break; case VariantTypeBoolean: m_data.boolean = rhs.m_data.boolean; diff --git a/xbmc/utils/Weather.cpp b/xbmc/utils/Weather.cpp index 83955b4562..26c8fb0af4 100644 --- a/xbmc/utils/Weather.cpp +++ b/xbmc/utils/Weather.cpp @@ -21,28 +21,32 @@ #if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS) #include "config.h" #endif + #include "Weather.h" -#include "filesystem/ZipManager.h" -#include "XMLUtils.h" -#include "utils/POUtils.h" -#include "utils/Temperature.h" -#include "network/Network.h" + +#include <utility> + +#include "addons/AddonManager.h" +#include "addons/GUIDialogAddonSettings.h" #include "Application.h" -#include "settings/lib/Setting.h" -#include "settings/Settings.h" +#include "filesystem/Directory.h" +#include "filesystem/ZipManager.h" #include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "guilib/WindowIDs.h" #include "GUIUserMessages.h" -#include "XBDateTime.h" +#include "interfaces/generic/ScriptInvocationManager.h" #include "LangInfo.h" -#include "guilib/WindowIDs.h" -#include "guilib/LocalizeStrings.h" -#include "filesystem/Directory.h" +#include "log.h" +#include "network/Network.h" +#include "settings/lib/Setting.h" +#include "settings/Settings.h" #include "StringUtils.h" #include "URIUtils.h" -#include "log.h" -#include "addons/AddonManager.h" -#include "interfaces/generic/ScriptInvocationManager.h" -#include "addons/GUIDialogAddonSettings.h" +#include "utils/POUtils.h" +#include "utils/Temperature.h" +#include "XBDateTime.h" +#include "XMLUtils.h" using namespace ADDON; using namespace XFILE; diff --git a/xbmc/utils/test/TestURIUtils.cpp b/xbmc/utils/test/TestURIUtils.cpp index ed02aea09d..1eb49a5c3e 100644 --- a/xbmc/utils/test/TestURIUtils.cpp +++ b/xbmc/utils/test/TestURIUtils.cpp @@ -18,13 +18,15 @@ * */ -#include "utils/URIUtils.h" -#include "settings/AdvancedSettings.h" -#include "filesystem/MultiPathDirectory.h" -#include "URL.h" +#include <utility> #include "gtest/gtest.h" +#include "filesystem/MultiPathDirectory.h" +#include "settings/AdvancedSettings.h" +#include "URL.h" +#include "utils/URIUtils.h" + using namespace XFILE; class TestURIUtils : public testing::Test diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index 5c4c2cd200..8b872cccc4 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -22,57 +22,57 @@ #include "config.h" #endif -#include "messaging/ApplicationMessenger.h" -#include "threads/SystemClock.h" #include "VideoDatabase.h" -#include "video/windows/GUIWindowVideoBase.h" + +#include <algorithm> +#include <map> +#include <memory> +#include <string> +#include <vector> + #include "addons/AddonManager.h" -#include "GUIInfoManager.h" -#include "Util.h" -#include "utils/URIUtils.h" -#include "utils/XMLUtils.h" -#include "GUIPassword.h" -#include "filesystem/StackDirectory.h" -#include "filesystem/MultiPathDirectory.h" -#include "VideoInfoScanner.h" -#include "guilib/GUIWindowManager.h" -#include "filesystem/Directory.h" -#include "filesystem/File.h" +#include "Application.h" +#include "dbwrappers/dataset.h" #include "dialogs/GUIDialogExtendedProgressBar.h" -#include "dialogs/GUIDialogProgress.h" -#include "dialogs/GUIDialogYesNo.h" #include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogOK.h" +#include "dialogs/GUIDialogProgress.h" +#include "dialogs/GUIDialogYesNo.h" #include "FileItem.h" +#include "filesystem/Directory.h" +#include "filesystem/File.h" +#include "filesystem/MultiPathDirectory.h" +#include "filesystem/StackDirectory.h" +#include "guiinfo/GUIInfoLabels.h" +#include "GUIInfoManager.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "GUIPassword.h" +#include "interfaces/AnnouncementManager.h" +#include "messaging/ApplicationMessenger.h" +#include "playlists/SmartPlayList.h" #include "profiles/ProfilesManager.h" #include "settings/AdvancedSettings.h" #include "settings/MediaSettings.h" #include "settings/MediaSourceSettings.h" #include "settings/Settings.h" #include "storage/MediaManager.h" -#include "utils/StringUtils.h" -#include "guilib/LocalizeStrings.h" -#include "utils/FileUtils.h" -#include "utils/log.h" #include "TextureCache.h" -#include "interfaces/AnnouncementManager.h" -#include "dbwrappers/dataset.h" -#include "utils/LabelFormatter.h" -#include "XBDateTime.h" +#include "threads/SystemClock.h" #include "URL.h" -#include "video/VideoDbUrl.h" -#include "playlists/SmartPlayList.h" +#include "Util.h" +#include "utils/FileUtils.h" #include "utils/GroupUtils.h" +#include "utils/LabelFormatter.h" +#include "utils/log.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" #include "utils/Variant.h" -#include "Application.h" -#include "guiinfo/GUIInfoLabels.h" - -#include <algorithm> -#include <map> -#include <memory> -#include <string> -#include <utility> -#include <vector> +#include "utils/XMLUtils.h" +#include "video/VideoDbUrl.h" +#include "video/windows/GUIWindowVideoBase.h" +#include "VideoInfoScanner.h" +#include "XBDateTime.h" using namespace dbiplus; using namespace XFILE; @@ -126,7 +126,7 @@ void CVideoDatabase::CreateTables() columns += StringUtils::Format(",c%02d text", i); columns += ", idSet integer, userrating integer)"; - m_pDS->exec(columns.c_str()); + m_pDS->exec(columns); CLog::Log(LOGINFO, "create actor table"); m_pDS->exec("CREATE TABLE actor ( actor_id INTEGER PRIMARY KEY, name TEXT, art_urls TEXT )"); @@ -147,7 +147,7 @@ void CVideoDatabase::CreateTables() columns += StringUtils::Format(",c%02d text", i); columns += ", userrating integer)"; - m_pDS->exec(columns.c_str()); + m_pDS->exec(columns); CLog::Log(LOGINFO, "create episode table"); columns = "CREATE TABLE episode ( idEpisode integer primary key, idFile integer"; @@ -162,7 +162,7 @@ void CVideoDatabase::CreateTables() columns += column; } columns += ", idShow integer, userrating integer)"; - m_pDS->exec(columns.c_str()); + m_pDS->exec(columns); CLog::Log(LOGINFO, "create tvshowlinkpath table"); m_pDS->exec("CREATE TABLE tvshowlinkpath (idShow integer, idPath integer)\n"); @@ -180,15 +180,15 @@ void CVideoDatabase::CreateTables() columns += StringUtils::Format(",c%02d text", i); columns += ", userrating integer)"; - m_pDS->exec(columns.c_str()); + m_pDS->exec(columns); CLog::Log(LOGINFO, "create streaminfo table"); m_pDS->exec("CREATE TABLE streamdetails (idFile integer, iStreamType integer, " "strVideoCodec text, fVideoAspect float, iVideoWidth integer, iVideoHeight integer, " "strAudioCodec text, iAudioChannels integer, strAudioLanguage text, strSubtitleLanguage text, iVideoDuration integer, strStereoMode text)"); - CLog::Log(LOGINFO, "create sets table"); - m_pDS->exec("CREATE TABLE sets ( idSet integer primary key, strSet text)\n"); + CLog::Log(LOGINFO, "create sets table"); + m_pDS->exec("CREATE TABLE sets ( idSet integer primary key, strSet text, strOverview text)"); CLog::Log(LOGINFO, "create seasons table"); m_pDS->exec("CREATE TABLE seasons ( idSeason integer primary key, idShow integer, season integer)"); @@ -248,9 +248,9 @@ void CVideoDatabase::CreateAnalytics() m_pDS->exec("CREATE UNIQUE INDEX ix_episode_file_1 on episode (idEpisode, idFile)"); m_pDS->exec("CREATE UNIQUE INDEX id_episode_file_2 on episode (idFile, idEpisode)"); std::string createColIndex = StringUtils::Format("CREATE INDEX ix_episode_season_episode on episode (c%02d, c%02d)", VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_EPISODE_EPISODE); - m_pDS->exec(createColIndex.c_str()); + m_pDS->exec(createColIndex); createColIndex = StringUtils::Format("CREATE INDEX ix_episode_bookmark on episode (c%02d)", VIDEODB_ID_EPISODE_BOOKMARK); - m_pDS->exec(createColIndex.c_str()); + m_pDS->exec(createColIndex); m_pDS->exec("CREATE INDEX ix_episode_show1 on episode(idEpisode,idShow)"); m_pDS->exec("CREATE INDEX ix_episode_show2 on episode(idShow,idEpisode)"); @@ -364,7 +364,7 @@ void CVideoDatabase::CreateViews() VIDEODB_ID_TV_TITLE, VIDEODB_ID_TV_GENRE, VIDEODB_ID_TV_STUDIOS, VIDEODB_ID_TV_PREMIERED, VIDEODB_ID_TV_MPAA, VIDEODB_ID_EPISODE_SEASON); - m_pDS->exec(episodeview.c_str()); + m_pDS->exec(episodeview); CLog::Log(LOGINFO, "create tvshowcounts"); std::string tvshowcounts = PrepareSQL("CREATE VIEW tvshowcounts AS SELECT " @@ -380,7 +380,7 @@ void CVideoDatabase::CreateViews() " LEFT JOIN files ON" " files.idFile=episode.idFile " " GROUP BY tvshow.idShow"); - m_pDS->exec(tvshowcounts.c_str()); + m_pDS->exec(tvshowcounts); CLog::Log(LOGINFO, "create tvshow_view"); std::string tvshowview = PrepareSQL("CREATE VIEW tvshow_view AS SELECT " @@ -397,7 +397,7 @@ void CVideoDatabase::CreateViews() " INNER JOIN tvshowcounts ON" " tvshow.idShow = tvshowcounts.idShow " "GROUP BY tvshow.idShow"); - m_pDS->exec(tvshowview.c_str()); + m_pDS->exec(tvshowview); CLog::Log(LOGINFO, "create season_view"); std::string seasonview = PrepareSQL("CREATE VIEW season_view AS SELECT " @@ -423,7 +423,7 @@ void CVideoDatabase::CreateViews() VIDEODB_ID_TV_TITLE, VIDEODB_ID_TV_PLOT, VIDEODB_ID_TV_PREMIERED, VIDEODB_ID_TV_GENRE, VIDEODB_ID_TV_STUDIOS, VIDEODB_ID_TV_MPAA, VIDEODB_ID_EPISODE_AIRED, VIDEODB_ID_EPISODE_SEASON); - m_pDS->exec(seasonview.c_str()); + m_pDS->exec(seasonview); CLog::Log(LOGINFO, "create musicvideo_view"); m_pDS->exec("CREATE VIEW musicvideo_view AS SELECT" @@ -447,6 +447,7 @@ void CVideoDatabase::CreateViews() m_pDS->exec("CREATE VIEW movie_view AS SELECT" " movie.*," " sets.strSet AS strSet," + " sets.strOverview AS strSetOverview," " files.strFileName AS strFileName," " path.strPath AS strPath," " files.playCount AS playCount," @@ -482,7 +483,7 @@ int CVideoDatabase::GetPathId(const std::string& strPath) URIUtils::AddSlashAtEnd(strPath1); strSQL=PrepareSQL("select idPath from path where strPath='%s'",strPath1.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (!m_pDS->eof()) idPath = m_pDS->fv("path.idPath").get_asInt(); @@ -572,7 +573,7 @@ bool CVideoDatabase::GetPathsLinkedToTvShow(int idShow, std::vector<std::string> try { sql = PrepareSQL("SELECT strPath FROM path JOIN tvshowlinkpath ON tvshowlinkpath.idPath=path.idPath WHERE idShow=%i", idShow); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); while (!m_pDS->eof()) { paths.push_back(m_pDS->fv(0).get_asString()); @@ -597,12 +598,12 @@ bool CVideoDatabase::GetPathsForTvShow(int idShow, std::set<int>& paths) // add base path strSQL = PrepareSQL("SELECT strPath FROM tvshow_view WHERE idShow=%i", idShow); - if (m_pDS->query(strSQL.c_str())) + if (m_pDS->query(strSQL)) paths.insert(GetPathId(m_pDS->fv(0).get_asString())); // add all other known paths strSQL = PrepareSQL("SELECT DISTINCT idPath FROM files JOIN episode ON episode.idFile=files.idFile WHERE episode.idShow=%i",idShow); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); while (!m_pDS->eof()) { paths.insert(m_pDS->fv(0).get_asInt()); @@ -622,7 +623,7 @@ int CVideoDatabase::RunQuery(const std::string &sql) { unsigned int time = XbmcThreads::SystemClockMillis(); int rows = -1; - if (m_pDS->query(sql.c_str())) + if (m_pDS->query(sql)) { rows = m_pDS->num_rows(); if (rows == 0) @@ -647,7 +648,7 @@ bool CVideoDatabase::GetSubPaths(const std::string &basepath, std::vector<std::p " AND idPath NOT IN (SELECT idPath FROM files WHERE strFileName LIKE 'index.bdmv')" , StringUtils::utf8_strlen(path.c_str()), path.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); while (!m_pDS->eof()) { subpaths.push_back(make_pair(m_pDS->fv(0).get_asInt(), m_pDS->fv(1).get_asString())); @@ -698,7 +699,7 @@ int CVideoDatabase::AddPath(const std::string& strPath, const std::string &paren else strSQL=PrepareSQL("insert into path (idPath, strPath, idParentPath) values (NULL, '%s', %i)", strPath1.c_str(), idParentPath); } - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); idPath = (int)m_pDS->lastinsertid(); return idPath; } @@ -717,7 +718,7 @@ bool CVideoDatabase::GetPathHash(const std::string &path, std::string &hash) if (NULL == m_pDS.get()) return false; std::string strSQL=PrepareSQL("select strHash from path where strPath='%s'", path.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) return false; hash = m_pDS->fv("strHash").get_asString(); @@ -762,7 +763,7 @@ bool CVideoDatabase::GetSourcePath(const std::string &path, std::string &sourceP "path.idPath = %i AND " "path.strContent IS NOT NULL AND path.strContent != '' AND " "path.strScraper IS NOT NULL AND path.strScraper != ''", idPath); - if (m_pDS->query(strSQL.c_str()) && !m_pDS->eof()) + if (m_pDS->query(strSQL) && !m_pDS->eof()) { settings.parent_name_root = settings.parent_name = m_pDS->fv(0).get_asBool(); settings.recurse = m_pDS->fv(1).get_asInt(); @@ -781,7 +782,7 @@ bool CVideoDatabase::GetSourcePath(const std::string &path, std::string &sourceP while (URIUtils::GetParentPath(strPath1, strParent)) { std::string strSQL = PrepareSQL("SELECT path.strContent, path.strScraper, path.scanRecursive, path.useFolderNames, path.noUpdate, path.exclude FROM path WHERE strPath = '%s'", strParent.c_str()); - if (m_pDS->query(strSQL.c_str()) && !m_pDS->eof()) + if (m_pDS->query(strSQL) && !m_pDS->eof()) { std::string strContent = m_pDS->fv(0).get_asString(); std::string strScraper = m_pDS->fv(1).get_asString(); @@ -832,7 +833,7 @@ int CVideoDatabase::AddFile(const std::string& strFileNameAndPath) std::string strSQL=PrepareSQL("select idFile from files where strFileName='%s' and idPath=%i", strFileName.c_str(),idPath); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() > 0) { idFile = m_pDS->fv("idFile").get_asInt() ; @@ -842,7 +843,7 @@ int CVideoDatabase::AddFile(const std::string& strFileNameAndPath) m_pDS->close(); strSQL=PrepareSQL("insert into files (idFile, idPath, strFileName) values(NULL, %i, '%s')", idPath, strFileName.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); idFile = (int)m_pDS->lastinsertid(); return idFile; } @@ -905,7 +906,7 @@ bool CVideoDatabase::SetPathHash(const std::string &path, const std::string &has if (idPath < 0) return false; std::string strSQL=PrepareSQL("update path set strHash='%s' where idPath=%ld", hash.c_str(), idPath); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } @@ -927,12 +928,12 @@ bool CVideoDatabase::LinkMovieToTvshow(int idMovie, int idShow, bool bRemove) if (bRemove) // delete link { std::string strSQL=PrepareSQL("delete from movielinktvshow where idMovie=%i and idShow=%i", idMovie, idShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } std::string strSQL=PrepareSQL("insert into movielinktvshow (idShow,idMovie) values (%i,%i)", idShow,idMovie); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return true; } @@ -952,7 +953,7 @@ bool CVideoDatabase::IsLinkedToTvshow(int idMovie) if (NULL == m_pDS.get()) return false; std::string strSQL=PrepareSQL("select * from movielinktvshow where idMovie=%i", idMovie); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->eof()) { m_pDS->close(); @@ -978,7 +979,7 @@ bool CVideoDatabase::GetLinksToTvShow(int idMovie, std::vector<int>& ids) if (NULL == m_pDS.get()) return false; std::string strSQL=PrepareSQL("select * from movielinktvshow where idMovie=%i", idMovie); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); while (!m_pDS2->eof()) { ids.push_back(m_pDS2->fv(1).get_asInt()); @@ -1012,7 +1013,7 @@ int CVideoDatabase::GetFileId(const std::string& strFilenameAndPath) { std::string strSQL; strSQL=PrepareSQL("select idFile from files where strFileName='%s' and idPath=%i", strFileName.c_str(),idPath); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() > 0) { int idFile = m_pDS->fv("files.idFile").get_asInt(); @@ -1074,7 +1075,7 @@ int CVideoDatabase::GetMovieId(const std::string& strFilenameAndPath) strSQL=PrepareSQL("select idMovie from movie where idFile=%i", idFile); CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, CURL::GetRedacted(strFilenameAndPath).c_str(), strSQL.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() > 0) idMovie = m_pDS->fv("idMovie").get_asInt(); m_pDS->close(); @@ -1107,14 +1108,14 @@ int CVideoDatabase::GetTvShowId(const std::string& strPath) int iFound=0; strSQL=PrepareSQL("select idShow from tvshowlinkpath where tvshowlinkpath.idPath=%i",idPath); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (!m_pDS->eof()) iFound = 1; while (iFound == 0 && URIUtils::GetParentPath(strPath1, strParent)) { strSQL=PrepareSQL("SELECT idShow FROM path INNER JOIN tvshowlinkpath ON tvshowlinkpath.idPath=path.idPath WHERE strPath='%s'",strParent.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (!m_pDS->eof()) { int idShow = m_pDS->fv("idShow").get_asInt(); @@ -1156,7 +1157,7 @@ int CVideoDatabase::GetEpisodeId(const std::string& strFilenameAndPath, int idEp std::string strSQL=PrepareSQL("select idEpisode from episode where idFile=%i", idFile); CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, CURL::GetRedacted(strFilenameAndPath).c_str(), strSQL.c_str()); - pDS->query(strSQL.c_str()); + pDS->query(strSQL); if (pDS->num_rows() > 0) { if (idEpisode == -1) @@ -1207,7 +1208,7 @@ int CVideoDatabase::GetMusicVideoId(const std::string& strFilenameAndPath) std::string strSQL=PrepareSQL("select idMVideo from musicvideo where idFile=%i", idFile); CLog::Log(LOGDEBUG, "%s (%s), query = %s", __FUNCTION__, CURL::GetRedacted(strFilenameAndPath).c_str(), strSQL.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); int idMVideo=-1; if (m_pDS->num_rows() > 0) idMVideo = m_pDS->fv("idMVideo").get_asInt(); @@ -1238,7 +1239,7 @@ int CVideoDatabase::AddMovie(const std::string& strFilenameAndPath) return -1; UpdateFileDateAdded(idFile, strFilenameAndPath); std::string strSQL=PrepareSQL("insert into movie (idMovie, idFile) values (NULL, %i)", idFile); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); idMovie = (int)m_pDS->lastinsertid(); } @@ -1313,7 +1314,7 @@ int CVideoDatabase::AddEpisode(int idShow, const std::string& strFilenameAndPath UpdateFileDateAdded(idFile, strFilenameAndPath); std::string strSQL=PrepareSQL("insert into episode (idEpisode, idFile, idShow) values (NULL, %i, %i)", idFile, idShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return (int)m_pDS->lastinsertid(); } catch (...) @@ -1338,7 +1339,7 @@ int CVideoDatabase::AddMusicVideo(const std::string& strFilenameAndPath) return -1; UpdateFileDateAdded(idFile, strFilenameAndPath); std::string strSQL=PrepareSQL("insert into musicvideo (idMVideo, idFile) values (NULL, %i)", idFile); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); idMVideo = (int)m_pDS->lastinsertid(); } @@ -1360,13 +1361,13 @@ int CVideoDatabase::AddToTable(const std::string& table, const std::string& firs if (NULL == m_pDS.get()) return -1; std::string strSQL = PrepareSQL("select %s from %s where %s like '%s'", firstField.c_str(), table.c_str(), secondField.c_str(), value.substr(0, 255).c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) { m_pDS->close(); // doesnt exists, add it strSQL = PrepareSQL("insert into %s (%s, %s) values(NULL, '%s')", table.c_str(), firstField.c_str(), secondField.c_str(), value.substr(0, 255).c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); int id = (int)m_pDS->lastinsertid(); return id; } @@ -1385,12 +1386,39 @@ int CVideoDatabase::AddToTable(const std::string& table, const std::string& firs return -1; } -int CVideoDatabase::AddSet(const std::string& strSet) +int CVideoDatabase::AddSet(const std::string& strSet, const std::string& strOverview /* = "" */) { if (strSet.empty()) return -1; - return AddToTable("sets", "idSet", "strSet", strSet); + try + { + if (m_pDB.get() == nullptr || m_pDS.get() == nullptr) + return -1; + + std::string strSQL = PrepareSQL("SELECT idSet FROM sets WHERE strSet LIKE '%s'", strSet.c_str()); + m_pDS->query(strSQL); + if (m_pDS->num_rows() == 0) + { + m_pDS->close(); + strSQL = PrepareSQL("INSERT INTO sets (idSet, strSet, strOverview) VALUES(NULL, '%s', '%s')", strSet.c_str(), strOverview.c_str()); + m_pDS->exec(strSQL); + int id = static_cast<int>(m_pDS->lastinsertid()); + return id; + } + else + { + int id = m_pDS->fv("idSet").get_asInt(); + m_pDS->close(); + return id; + } + } + catch (...) + { + CLog::Log(LOGERROR, "%s (%s) failed", __FUNCTION__, strSet.c_str()); + } + + return -1; } int CVideoDatabase::AddTag(const std::string& name) @@ -1414,13 +1442,13 @@ int CVideoDatabase::AddActor(const std::string& name, const std::string& thumbUR StringUtils::Trim(trimmedName); std::string strSQL=PrepareSQL("select actor_id from actor where name like '%s'", trimmedName.substr(0, 255).c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (m_pDS->num_rows() == 0) { m_pDS->close(); // doesnt exists, add it strSQL=PrepareSQL("insert into actor (actor_id, name, art_urls) values(NULL, '%s', '%s')", trimmedName.substr(0,255).c_str(), thumbURLs.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); idActor = (int)m_pDS->lastinsertid(); } else @@ -1431,7 +1459,7 @@ int CVideoDatabase::AddActor(const std::string& name, const std::string& thumbUR if (!thumbURLs.empty()) { strSQL=PrepareSQL("update actor set art_urls = '%s' where actor_id = %i", thumbURLs.c_str(), idActor); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } } // add artwork @@ -1655,16 +1683,16 @@ void CVideoDatabase::DeleteDetailsForTvShow(int idTvShow) std::string strSQL; strSQL=PrepareSQL("DELETE from genre_link WHERE media_id=%i AND media_type='tvshow'", idTvShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); strSQL=PrepareSQL("DELETE FROM actor_link WHERE media_id=%i AND media_type='tvshow'", idTvShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); strSQL=PrepareSQL("DELETE FROM director_link WHERE media_id=%i AND media_type='tvshow'", idTvShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); strSQL=PrepareSQL("DELETE FROM studio_link WHERE media_id=%i AND media_type='tvshow'", idTvShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); // remove all info other than the id // we do this due to the way we have the link between the file + movie tables. @@ -1676,7 +1704,7 @@ void CVideoDatabase::DeleteDetailsForTvShow(int idTvShow) strSQL = "update tvshow set "; strSQL += StringUtils::Join(ids, ", "); strSQL += PrepareSQL(" where idShow=%i", idTvShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -1733,7 +1761,7 @@ void CVideoDatabase::GetMusicVideosByArtist(const std::string& strArtist, CFileI strSQL=PrepareSQL("select distinct * from musicvideo_view join actor_link on actor_link.media_id=musicvideo_view.idMVideo AND actor_link.media_type='musicvideo' join actor on actor.actor_id=actor_link.actor_id"); else strSQL=PrepareSQL("select * from musicvideo_view join actor_link on actor_link.media_id=musicvideo_view.idMVideo AND actor_link.media_type='musicvideo' join actor on actor.actor_id=actor_link.actor_id where actor.name='%s'", strArtist.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -1762,7 +1790,7 @@ bool CVideoDatabase::GetMovieInfo(const std::string& strFilenameAndPath, CVideoI if (idMovie < 0) return false; std::string sql = PrepareSQL("select * from movie_view where idMovie=%i", idMovie); - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(sql)) return false; details = GetDetailsForMovie(m_pDS, true); return !details.IsEmpty(); @@ -1784,7 +1812,7 @@ bool CVideoDatabase::GetTvShowInfo(const std::string& strPath, CVideoInfoTag& de if (idTvShow < 0) return false; std::string sql = PrepareSQL("SELECT * FROM tvshow_view WHERE idShow=%i GROUP BY idShow", idTvShow); - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(sql)) return false; details = GetDetailsForTvShow(m_pDS, true, item); return !details.IsEmpty(); @@ -1807,7 +1835,7 @@ bool CVideoDatabase::GetSeasonInfo(int idSeason, CVideoInfoTag& details) return false; std::string sql = PrepareSQL("SELECT idShow FROM seasons WHERE idSeason=%i", idSeason); - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(sql)) return false; int idShow = -1; @@ -1850,7 +1878,7 @@ bool CVideoDatabase::GetEpisodeInfo(const std::string& strFilenameAndPath, CVide if (idEpisode < 0) return false; std::string sql = PrepareSQL("select * from episode_view where idEpisode=%i",idEpisode); - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(sql)) return false; details = GetDetailsForEpisode(m_pDS, true); return !details.IsEmpty(); @@ -1872,7 +1900,7 @@ bool CVideoDatabase::GetMusicVideoInfo(const std::string& strFilenameAndPath, CV if (idMVideo < 0) return false; std::string sql = PrepareSQL("select * from musicvideo_view where idMVideo=%i", idMVideo); - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(sql)) return false; details = GetDetailsForMusicVideo(m_pDS, true); return !details.IsEmpty(); @@ -1922,7 +1950,7 @@ bool CVideoDatabase::GetFileInfo(const std::string& strFilenameAndPath, CVideoIn "JOIN path ON path.idPath = files.idPath " "LEFT JOIN bookmark ON bookmark.idFile = files.idFile AND bookmark.type = %i " "WHERE files.idFile = %i", CBookmark::RESUME, idFile); - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(sql)) return false; details.m_iFileId = m_pDS->fv("files.idFile").get_asInt(); @@ -2066,7 +2094,7 @@ int CVideoDatabase::SetDetailsForMovie(const std::string& strFilenameAndPath, co int idSet = -1; if (!details.m_strSet.empty()) { - idSet = AddSet(details.m_strSet); + idSet = AddSet(details.m_strSet, details.m_strSetOverview); // add art if not available std::map<std::string, std::string> setArt; if (!GetArtForItem(idSet, MediaTypeVideoCollection, setArt)) @@ -2081,7 +2109,7 @@ int CVideoDatabase::SetDetailsForMovie(const std::string& strFilenameAndPath, co if (!details.m_strIMDBNumber.empty() && details.m_iYear) { // query DB for any movies matching imdbid and year std::string strSQL = PrepareSQL("SELECT files.playCount, files.lastPlayed FROM movie INNER JOIN files ON files.idFile=movie.idFile WHERE movie.c%02d='%s' AND movie.c%02d=%i AND movie.idMovie!=%i AND files.playCount > 0", VIDEODB_ID_IDENT, details.m_strIMDBNumber.c_str(), VIDEODB_ID_YEAR, details.m_iYear, idMovie); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (!m_pDS->eof()) { @@ -2094,7 +2122,7 @@ int CVideoDatabase::SetDetailsForMovie(const std::string& strFilenameAndPath, co // update with playCount and lastPlayed strSQL = PrepareSQL("update files set playCount=%i,lastPlayed='%s' where idFile=%i", playCount, lastPlayed.GetAsDBDateTime().c_str(), idFile); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } m_pDS->close(); @@ -2111,7 +2139,7 @@ int CVideoDatabase::SetDetailsForMovie(const std::string& strFilenameAndPath, co else sql += ", userrating = NULL"; sql += PrepareSQL(" where idMovie=%i", idMovie); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CommitTransaction(); return idMovie; @@ -2158,7 +2186,7 @@ int CVideoDatabase::UpdateDetailsForMovie(int idMovie, const CVideoInfoTag& deta idSet = -1; if (!details.m_strSet.empty()) { - idSet = AddSet(details.m_strSet); + idSet = AddSet(details.m_strSet, details.m_strSetOverview); // add art if not available std::map<std::string, std::string> setArt; if (!GetArtForItem(idSet, "set", setArt)) @@ -2223,7 +2251,7 @@ int CVideoDatabase::SetDetailsForMovieSet(const CVideoInfoTag& details, const st BeginTransaction(); if (idSet < 0) { - idSet = AddSet(details.m_strTitle); + idSet = AddSet(details.m_strTitle, details.m_strPlot); if (idSet < 0) { RollbackTransaction(); @@ -2234,8 +2262,8 @@ int CVideoDatabase::SetDetailsForMovieSet(const CVideoInfoTag& details, const st SetArtForItem(idSet, MediaTypeVideoCollection, artwork); // and insert the new row - std::string sql = PrepareSQL("UPDATE sets SET strSet='%s' WHERE idSet=%i", details.m_strTitle.c_str(), idSet); - m_pDS->exec(sql.c_str()); + std::string sql = PrepareSQL("UPDATE sets SET strSet='%s', strOverview='%s' WHERE idSet=%i", details.m_strTitle.c_str(), details.m_strPlot.c_str(), idSet); + m_pDS->exec(sql); CommitTransaction(); return idSet; @@ -2363,7 +2391,7 @@ int CVideoDatabase::SetDetailsForSeason(const CVideoInfoTag& details, const std: // and insert the new row std::string sql = PrepareSQL("UPDATE seasons SET season=%i WHERE idSeason=%i", details.m_iSeason, idSeason); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CommitTransaction(); return idSeason; @@ -2420,7 +2448,7 @@ int CVideoDatabase::SetDetailsForEpisode(const std::string& strFilenameAndPath, if (details.m_iEpisode != -1 && details.m_iSeason != -1) { // query DB for any episodes matching idShow, Season and Episode std::string strSQL = PrepareSQL("SELECT files.playCount, files.lastPlayed FROM episode INNER JOIN files ON files.idFile=episode.idFile WHERE episode.c%02d=%i AND episode.c%02d=%i AND episode.idShow=%i AND episode.idEpisode!=%i AND files.playCount > 0", VIDEODB_ID_EPISODE_SEASON, details.m_iSeason, VIDEODB_ID_EPISODE_EPISODE, details.m_iEpisode, idShow, idEpisode); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); if (!m_pDS->eof()) { @@ -2433,7 +2461,7 @@ int CVideoDatabase::SetDetailsForEpisode(const std::string& strFilenameAndPath, // update with playCount and lastPlayed strSQL = PrepareSQL("update files set playCount=%i,lastPlayed='%s' where idFile=%i", playCount, lastPlayed.GetAsDBDateTime().c_str(), idFile); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } m_pDS->close(); @@ -2445,7 +2473,7 @@ int CVideoDatabase::SetDetailsForEpisode(const std::string& strFilenameAndPath, else sql += ", userrating = NULL"; sql += PrepareSQL(" where idEpisode=%i", idEpisode); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CommitTransaction(); return idEpisode; @@ -2522,7 +2550,7 @@ int CVideoDatabase::SetDetailsForMusicVideo(const std::string& strFilenameAndPat else sql += ", userrating = NULL"; sql += PrepareSQL(" where idMVideo=%i", idMVideo); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CommitTransaction(); return idMVideo; @@ -2626,7 +2654,7 @@ void CVideoDatabase::GetFilePathById(int idMovie, std::string &filePath, VIDEODB if (iType ==VIDEODB_CONTENT_MUSICVIDEOS) strSQL=PrepareSQL("SELECT path.strPath, files.strFileName FROM path INNER JOIN files ON path.idPath=files.idPath INNER JOIN musicvideo ON files.idFile=musicvideo.idFile WHERE musicvideo.idMVideo=%i ORDER BY strFilename", idMovie ); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (!m_pDS->eof()) { if (iType != VIDEODB_CONTENT_TVSHOWS) @@ -2671,7 +2699,7 @@ void CVideoDatabase::GetBookMarksForFile(const std::string& strFilenameAndPath, if (NULL == m_pDS.get()) return ; std::string strSQL=PrepareSQL("select * from bookmark where idFile=%i and type=%i order by timeInSeconds", idFile, (int)type); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { CBookmark bookmark; @@ -2685,7 +2713,7 @@ void CVideoDatabase::GetBookMarksForFile(const std::string& strFilenameAndPath, if (type == CBookmark::EPISODE) { std::string strSQL2=PrepareSQL("select c%02d, c%02d from episode where c%02d=%i order by c%02d, c%02d", VIDEODB_ID_EPISODE_EPISODE, VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_EPISODE_BOOKMARK, m_pDS->fv("idBookmark").get_asInt(), VIDEODB_ID_EPISODE_SORTSEASON, VIDEODB_ID_EPISODE_SORTEPISODE); - m_pDS2->query(strSQL2.c_str()); + m_pDS2->query(strSQL2); bookmark.episodeNumber = m_pDS2->fv(0).get_asInt(); bookmark.seasonNumber = m_pDS2->fv(1).get_asInt(); m_pDS2->close(); @@ -2727,7 +2755,7 @@ void CVideoDatabase::DeleteResumeBookMark(const std::string &strFilenameAndPath) try { std::string sql = PrepareSQL("delete from bookmark where idFile=%i and type=%i", fileID, CBookmark::RESUME); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } catch(...) { @@ -2740,7 +2768,7 @@ void CVideoDatabase::GetEpisodesByFile(const std::string& strFilenameAndPath, st try { std::string strSQL = PrepareSQL("select * from episode_view where idFile=%i order by c%02d, c%02d asc", GetFileId(strFilenameAndPath), VIDEODB_ID_EPISODE_SORTSEASON, VIDEODB_ID_EPISODE_SORTEPISODE); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); while (!m_pDS->eof()) { episodes.push_back(GetDetailsForEpisode(m_pDS)); @@ -2782,7 +2810,7 @@ void CVideoDatabase::AddBookMarkToFile(const std::string& strFilenameAndPath, co if (type != CBookmark::EPISODE) { // get current id - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() != 0) idBookmark = m_pDS->get_field_value("idBookmark").get_asInt(); m_pDS->close(); @@ -2793,7 +2821,7 @@ void CVideoDatabase::AddBookMarkToFile(const std::string& strFilenameAndPath, co else strSQL=PrepareSQL("insert into bookmark (idBookmark, idFile, timeInSeconds, totalTimeInSeconds, thumbNailImage, player, playerState, type) values(NULL,%i,%f,%f,'%s','%s','%s', %i)", idFile, bookmark.timeInSeconds, bookmark.totalTimeInSeconds, bookmark.thumbNailImage.c_str(), bookmark.player.c_str(), bookmark.playerState.c_str(), (int)type); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -2816,16 +2844,16 @@ void CVideoDatabase::ClearBookMarkOfFile(const std::string& strFilenameAndPath, double maxtime = bookmark.timeInSeconds + 0.5f; std::string strSQL = PrepareSQL("select idBookmark from bookmark where idFile=%i and type=%i and playerState like '%s' and player like '%s' and (timeInSeconds between %f and %f)", idFile, type, bookmark.playerState.c_str(), bookmark.player.c_str(), mintime, maxtime); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() != 0) { int idBookmark = m_pDS->get_field_value("idBookmark").get_asInt(); strSQL=PrepareSQL("delete from bookmark where idBookmark=%i",idBookmark); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); if (type == CBookmark::EPISODE) { strSQL=PrepareSQL("update episode set c%02d=-1 where idFile=%i and c%02d=%i", VIDEODB_ID_EPISODE_BOOKMARK, idFile, VIDEODB_ID_EPISODE_BOOKMARK, idBookmark); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } } @@ -2856,11 +2884,11 @@ void CVideoDatabase::ClearBookMarksOfFile(int idFile, CBookmark::EType type /*= if (NULL == m_pDS.get()) return ; std::string strSQL=PrepareSQL("delete from bookmark where idFile=%i and type=%i", idFile, (int)type); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); if (type == CBookmark::EPISODE) { strSQL=PrepareSQL("update episode set c%02d=-1 where idFile=%i", VIDEODB_ID_EPISODE_BOOKMARK, idFile); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } } catch (...) @@ -2875,7 +2903,7 @@ bool CVideoDatabase::GetBookMarkForEpisode(const CVideoInfoTag& tag, CBookmark& try { std::string strSQL = PrepareSQL("select bookmark.* from bookmark join episode on episode.c%02d=bookmark.idBookmark where episode.idEpisode=%i", VIDEODB_ID_EPISODE_BOOKMARK, tag.m_iDbId); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (!m_pDS->eof()) { bookmark.timeInSeconds = m_pDS->fv("timeInSeconds").get_asDouble(); @@ -2907,12 +2935,12 @@ void CVideoDatabase::AddBookMarkForEpisode(const CVideoInfoTag& tag, const CBook int idFile = GetFileId(tag.m_strFileNameAndPath); // delete the current episode for the selected episode number std::string strSQL = PrepareSQL("delete from bookmark where idBookmark in (select c%02d from episode where c%02d=%i and c%02d=%i and idFile=%i)", VIDEODB_ID_EPISODE_BOOKMARK, VIDEODB_ID_EPISODE_SEASON, tag.m_iSeason, VIDEODB_ID_EPISODE_EPISODE, tag.m_iEpisode, idFile); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); AddBookMarkToFile(tag.m_strFileNameAndPath, bookmark, CBookmark::EPISODE); int idBookmark = (int)m_pDS->lastinsertid(); strSQL = PrepareSQL("update episode set c%02d=%i where c%02d=%i and c%02d=%i and idFile=%i", VIDEODB_ID_EPISODE_BOOKMARK, idBookmark, VIDEODB_ID_EPISODE_SEASON, tag.m_iSeason, VIDEODB_ID_EPISODE_EPISODE, tag.m_iEpisode, idFile); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -2925,9 +2953,9 @@ void CVideoDatabase::DeleteBookMarkForEpisode(const CVideoInfoTag& tag) try { std::string strSQL = PrepareSQL("delete from bookmark where idBookmark in (select c%02d from episode where idEpisode=%i)", VIDEODB_ID_EPISODE_BOOKMARK, tag.m_iDbId); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); strSQL = PrepareSQL("update episode set c%02d=-1 where idEpisode=%i", VIDEODB_ID_EPISODE_BOOKMARK, tag.m_iDbId); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -2966,7 +2994,7 @@ void CVideoDatabase::DeleteMovie(int idMovie, bool bKeepId /* = false */) InvalidatePathHash(path); std::string strSQL = PrepareSQL("delete from movie where idMovie=%i", idMovie); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } // TODO: move this below CommitTransaction() once UPnP doesn't rely on this anymore @@ -3006,7 +3034,7 @@ void CVideoDatabase::DeleteTvShow(int idTvShow, bool bKeepId /* = false */) GetPathsForTvShow(idTvShow, paths); std::string strSQL=PrepareSQL("SELECT episode.idEpisode FROM episode WHERE episode.idShow=%i",idTvShow); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); while (!m_pDS2->eof()) { DeleteEpisode(m_pDS2->fv(0).get_asInt(), bKeepId); @@ -3016,13 +3044,13 @@ void CVideoDatabase::DeleteTvShow(int idTvShow, bool bKeepId /* = false */) DeleteDetailsForTvShow(idTvShow); strSQL=PrepareSQL("delete from seasons where idShow=%i", idTvShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); // keep tvshow table and movielink table so we can update data in place if (!bKeepId) { strSQL=PrepareSQL("delete from tvshow where idShow=%i", idTvShow); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); for (std::set<int>::const_iterator i = paths.begin(); i != paths.end(); ++i) { @@ -3063,7 +3091,7 @@ void CVideoDatabase::DeleteSeason(int idSeason, bool bKeepId /* = false */) std::string strSQL = PrepareSQL("SELECT episode.idEpisode FROM episode " "JOIN seasons ON seasons.idSeason = %d AND episode.idShow = seasons.idShow AND episode.c%02d = seasons.season ", idSeason, VIDEODB_ID_EPISODE_SEASON); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); while (!m_pDS2->eof()) { DeleteEpisode(m_pDS2->fv(0).get_asInt(), bKeepId); @@ -3112,7 +3140,7 @@ void CVideoDatabase::DeleteEpisode(int idEpisode, bool bKeepId /* = false */) InvalidatePathHash(path); std::string strSQL = PrepareSQL("delete from episode where idEpisode=%i", idEpisode); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } } @@ -3151,7 +3179,7 @@ void CVideoDatabase::DeleteMusicVideo(int idMVideo, bool bKeepId /* = false */) InvalidatePathHash(path); std::string strSQL = PrepareSQL("delete from musicvideo where idMVideo=%i", idMVideo); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } //TODO: move this below CommitTransaction() once UPnP doesn't rely on this anymore @@ -3194,9 +3222,9 @@ void CVideoDatabase::DeleteSet(int idSet) std::string strSQL; strSQL=PrepareSQL("delete from sets where idSet = %i", idSet); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); strSQL=PrepareSQL("update movie set idSet = null where idSet = %i", idSet); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -3235,7 +3263,7 @@ void CVideoDatabase::DeleteTag(int idTag, VIDEODB_CONTENT_TYPE mediaType) return; std::string strSQL = PrepareSQL("DELETE FROM tag_link WHERE tag_id = %i AND media_type = '%s'", idTag, type.c_str()); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -3346,7 +3374,7 @@ bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag) const try { std::string strSQL = PrepareSQL("SELECT * FROM streamdetails WHERE idFile = %i", tag.m_iFileId); - pDS->query(strSQL.c_str()); + pDS->query(strSQL); while (!pDS->eof()) { @@ -3437,7 +3465,7 @@ bool CVideoDatabase::GetResumePoint(CVideoInfoTag& tag) else { std::string strSQL=PrepareSQL("select timeInSeconds, totalTimeInSeconds from bookmark where idFile=%i and type=%i order by timeInSeconds", tag.m_iFileId, CBookmark::RESUME); - m_pDS2->query( strSQL.c_str() ); + m_pDS2->query( strSQL ); if (!m_pDS2->eof()) { tag.m_resumePoint.timeInSeconds = m_pDS2->fv(0).get_asDouble(); @@ -3479,6 +3507,7 @@ CVideoInfoTag CVideoDatabase::GetDetailsForMovie(const dbiplus::sql_record* cons details.m_iSetId = record->at(VIDEODB_DETAILS_MOVIE_SET_ID).get_asInt(); details.m_strSet = record->at(VIDEODB_DETAILS_MOVIE_SET_NAME).get_asString(); + details.m_strSetOverview = record->at(VIDEODB_DETAILS_MOVIE_SET_OVERVIEW).get_asString(); details.m_iFileId = record->at(VIDEODB_DETAILS_FILEID).get_asInt(); details.m_strPath = record->at(VIDEODB_DETAILS_MOVIE_PATH).get_asString(); std::string strFileName = record->at(VIDEODB_DETAILS_MOVIE_FILE).get_asString(); @@ -3507,7 +3536,7 @@ CVideoInfoTag CVideoDatabase::GetDetailsForMovie(const dbiplus::sql_record* cons { std::string strSQL = PrepareSQL("select c%02d from tvshow where idShow=%i", VIDEODB_ID_TV_TITLE,links[i]); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); if (!m_pDS2->eof()) details.m_showLink.push_back(m_pDS2->fv(0).get_asString()); } @@ -3623,7 +3652,7 @@ CVideoInfoTag CVideoDatabase::GetDetailsForEpisode(const dbiplus::sql_record* co castTime += XbmcThreads::SystemClockMillis() - time; time = XbmcThreads::SystemClockMillis(); details.m_strPictureURL.Parse(); std::string strSQL = PrepareSQL("select * from bookmark join episode on episode.c%02d=bookmark.idBookmark where episode.idEpisode=%i and bookmark.type=%i", VIDEODB_ID_EPISODE_BOOKMARK,details.m_iDbId,CBookmark::EPISODE); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); if (!m_pDS2->eof()) details.m_fEpBookmark = m_pDS2->fv("bookmark.timeInSeconds").get_asFloat(); m_pDS2->close(); @@ -3770,7 +3799,7 @@ bool CVideoDatabase::GetVideoSettings(int idFile, CVideoSettings &settings) if (NULL == m_pDS.get()) return false; std::string strSQL=PrepareSQL("select * from settings where settings.idFile = '%i'", idFile); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() > 0) { // get the video settings info @@ -3822,7 +3851,7 @@ void CVideoDatabase::SetVideoSettings(const std::string& strFilenameAndPath, con if (idFile < 0) return; std::string strSQL = PrepareSQL("select * from settings where idFile=%i", idFile); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() > 0) { m_pDS->close(); @@ -3839,7 +3868,7 @@ void CVideoDatabase::SetVideoSettings(const std::string& strFilenameAndPath, con std::string strSQL2; strSQL2=PrepareSQL("ResumeTime=%i,StereoMode=%i,StereoInvert=%i where idFile=%i\n", setting.m_ResumeTime, setting.m_StereoMode, setting.m_StereoInvert, idFile); strSQL += strSQL2; - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); return ; } else @@ -3858,7 +3887,7 @@ void CVideoDatabase::SetVideoSettings(const std::string& strFilenameAndPath, con setting.m_ResumeTime, setting.m_Sharpness, setting.m_NoiseReduction, setting.m_CustomNonLinStretch, setting.m_PostProcess, setting.m_ScalingMethod, setting.m_DeinterlaceMode, setting.m_StereoMode, setting.m_StereoInvert); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } } catch (...) @@ -3885,7 +3914,7 @@ void CVideoDatabase::SetArtForItem(int mediaId, const MediaType &mediaType, cons return; std::string sql = PrepareSQL("SELECT art_id,url FROM art WHERE media_id=%i AND media_type='%s' AND type='%s'", mediaId, mediaType.c_str(), artType.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // update int artId = m_pDS->fv(0).get_asInt(); @@ -3894,14 +3923,14 @@ void CVideoDatabase::SetArtForItem(int mediaId, const MediaType &mediaType, cons if (oldUrl != url) { sql = PrepareSQL("UPDATE art SET url='%s' where art_id=%d", url.c_str(), artId); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } } else { // insert m_pDS->close(); sql = PrepareSQL("INSERT INTO art(media_id, media_type, type, url) VALUES (%d, '%s', '%s', '%s')", mediaId, mediaType.c_str(), artType.c_str(), url.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } } catch (...) @@ -3918,7 +3947,7 @@ bool CVideoDatabase::GetArtForItem(int mediaId, const MediaType &mediaType, std: if (NULL == m_pDS2.get()) return false; // using dataset 2 as we're likely called in loops on dataset 1 std::string sql = PrepareSQL("SELECT type,url FROM art WHERE media_id=%i AND media_type='%s'", mediaId, mediaType.c_str()); - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); while (!m_pDS2->eof()) { art.insert(make_pair(m_pDS2->fv(0).get_asString(), m_pDS2->fv(1).get_asString())); @@ -3963,7 +3992,7 @@ bool CVideoDatabase::GetTvShowSeasons(int showId, std::map<int, int> &seasons) // get all seasons for this show std::string sql = PrepareSQL("select idSeason,season from seasons where idShow=%i", showId); - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); seasons.clear(); while (!m_pDS2->eof()) @@ -4046,7 +4075,7 @@ bool CVideoDatabase::GetStackTimes(const std::string &filePath, std::vector<int> if (NULL == m_pDS.get()) return false; // ok, now obtain the settings for this file std::string strSQL=PrepareSQL("select times from stacktimes where idFile=%i\n", idFile); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->num_rows() > 0) { // get the video settings info int timeTotal = 0; @@ -4139,11 +4168,11 @@ void CVideoDatabase::RemoveContentForPath(const std::string& strPath, CGUIDialog else { std::string strSQL = PrepareSQL("select files.strFilename from files join movie on movie.idFile=files.idFile where files.idPath=%i", i->first); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); if (m_pDS2->eof()) { strSQL = PrepareSQL("select files.strFilename from files join musicvideo on musicvideo.idFile=files.idFile where files.idPath=%i", i->first); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); bMvidsChecked = true; } while (!m_pDS2->eof()) @@ -4159,7 +4188,7 @@ void CVideoDatabase::RemoveContentForPath(const std::string& strPath, CGUIDialog if (m_pDS2->eof() && !bMvidsChecked) { strSQL =PrepareSQL("select files.strFilename from files join musicvideo on musicvideo.idFile=files.idFile where files.idPath=%i", i->first); - m_pDS2->query(strSQL.c_str()); + m_pDS2->query(strSQL); bMvidsChecked = true; } } @@ -4214,7 +4243,7 @@ void CVideoDatabase::SetScraperForPath(const std::string& filePath, const Scrape std::string content = TranslateContent(scraper->Content()); strSQL=PrepareSQL("update path set strContent='%s', strScraper='%s', scanRecursive=%i, useFolderNames=%i, strSettings='%s', noUpdate=%i, exclude=0 where idPath=%i", content.c_str(), scraper->ID().c_str(),settings.recurse,settings.parent_name,scraper->GetPathSettings().c_str(),settings.noupdate, idPath); } - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } catch (...) { @@ -4230,7 +4259,7 @@ bool CVideoDatabase::ScraperInUse(const std::string &scraperID) const if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("select count(1) from path where strScraper='%s'", scraperID.c_str()); - if (!m_pDS->query(sql.c_str()) || m_pDS->num_rows() == 0) + if (!m_pDS->query(sql) || m_pDS->num_rows() == 0) return false; bool found = m_pDS->fv(0).get_asInt() > 0; m_pDS->close(); @@ -4317,7 +4346,7 @@ void CVideoDatabase::UpdateTables(int iVersion) { // drop duplicates in tvshow table, and update tvshowlinkpath accordingly std::string sql = PrepareSQL("SELECT tvshow.idShow,idPath,c%02d,c%02d,c%02d FROM tvshow JOIN tvshowlinkpath ON tvshow.idShow = tvshowlinkpath.idShow", VIDEODB_ID_TV_TITLE, VIDEODB_ID_TV_PREMIERED, VIDEODB_ID_TV_IDENT); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); std::vector<CShowItem> shows; while (!m_pDS->eof()) { @@ -4602,11 +4631,14 @@ void CVideoDatabase::UpdateTables(int iVersion) m_pDS->exec("ALTER TABLE tvshow ADD userrating integer"); m_pDS->exec("ALTER TABLE musicvideo ADD userrating integer"); } + + if (iVersion < 97) + m_pDS->exec("ALTER TABLE sets ADD strOverview TEXT"); } int CVideoDatabase::GetSchemaVersion() const { - return 96; + return 97; } bool CVideoDatabase::LookupByFolders(const std::string &path, bool shows) @@ -4702,7 +4734,7 @@ int CVideoDatabase::GetPlayCount(int iFileId) std::string strSQL = PrepareSQL("select playCount from files WHERE idFile=%i", iFileId); int count = 0; - if (m_pDS->query(strSQL.c_str())) + if (m_pDS->query(strSQL)) { // there should only ever be one row returned if (m_pDS->num_rows() == 1) @@ -4742,7 +4774,7 @@ void CVideoDatabase::UpdateFanart(const CFileItem &item, VIDEODB_CONTENT_TYPE ty try { - m_pDS->exec(exec.c_str()); + m_pDS->exec(exec); if (type == VIDEODB_CONTENT_TVSHOWS) AnnounceUpdate(MediaTypeTvShow, item.GetVideoInfoTag()->m_iDbId); @@ -4792,7 +4824,7 @@ void CVideoDatabase::SetPlayCount(const CFileItem &item, int count, const CDateT strSQL = PrepareSQL("update files set playCount=NULL,lastPlayed='%s' where idFile=%i", date.GetAsDBDateTime().c_str(), id); } - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); // We only need to announce changes to video items in the library if (item.HasVideoInfoTag() && item.GetVideoInfoTag()->m_iDbId > 0) @@ -4853,7 +4885,7 @@ void CVideoDatabase::UpdateMovieTitle(int idMovie, const std::string& strNewMovi { CLog::Log(LOGINFO, "Changing Movie set:id:%i New Title:%s", idMovie, strNewMovieTitle.c_str()); std::string strSQL = PrepareSQL("UPDATE sets SET strSet='%s' WHERE idSet=%i", strNewMovieTitle.c_str(), idMovie ); - m_pDS->exec(strSQL.c_str()); + m_pDS->exec(strSQL); } if (!content.empty()) @@ -5162,7 +5194,8 @@ bool CVideoDatabase::GetSetsByWhere(const std::string& strBaseDir, const Filter return false; CFileItemList sets; - if (!GroupUtils::Group(GroupBySet, strBaseDir, items, sets)) + GroupAttribute groupingAttributes = ignoreSingleMovieSets ? GroupAttributeIgnoreSingleItems : GroupAttributeNone; + if (!GroupUtils::Group(GroupBySet, strBaseDir, items, sets, groupingAttributes)) return false; items.ClearItems(); @@ -5452,7 +5485,7 @@ bool CVideoDatabase::GetPeopleNav(const std::string& strBaseDir, CFileItemList& // run query unsigned int time = XbmcThreads::SystemClockMillis(); - if (!m_pDS->query(strSQL.c_str())) return false; + if (!m_pDS->query(strSQL)) return false; CLog::Log(LOGDEBUG, "%s - query took %i ms", __FUNCTION__, XbmcThreads::SystemClockMillis() - time); time = XbmcThreads::SystemClockMillis(); int iRowsFound = m_pDS->num_rows(); @@ -5960,7 +5993,7 @@ bool CVideoDatabase::GetItems(const std::string &strBaseDir, VIDEODB_CONTENT_TYP else if (StringUtils::EqualsNoCase(itemType, "studios")) return GetStudiosNav(strBaseDir, items, mediaType, filter); else if (StringUtils::EqualsNoCase(itemType, "sets")) - return GetSetsNav(strBaseDir, items, mediaType, filter); + return GetSetsNav(strBaseDir, items, mediaType, filter, !CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOLIBRARY_GROUPSINGLEITEMSETS)); else if (StringUtils::EqualsNoCase(itemType, "countries")) return GetCountriesNav(strBaseDir, items, mediaType, filter); else if (StringUtils::EqualsNoCase(itemType, "tags")) @@ -6476,7 +6509,7 @@ int CVideoDatabase::GetTvShowForEpisode(int idEpisode) // make sure we use m_pDS2, as this is called in loops using m_pDS std::string strSQL=PrepareSQL("select idShow from episode where idEpisode=%i", idEpisode); - m_pDS2->query( strSQL.c_str() ); + m_pDS2->query( strSQL ); int result=-1; if (!m_pDS2->eof()) @@ -6524,7 +6557,7 @@ bool CVideoDatabase::HasContent(VIDEODB_CONTENT_TYPE type) sql = "select count(1) from tvshow"; else if (type == VIDEODB_CONTENT_MUSICVIDEOS) sql = "select count(1) from musicvideo"; - m_pDS->query( sql.c_str() ); + m_pDS->query( sql ); if (!m_pDS->eof()) result = (m_pDS->fv(0).get_asInt() > 0); @@ -6571,7 +6604,7 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe if (idPath > -1) { std::string strSQL=PrepareSQL("select path.strContent,path.strScraper,path.scanRecursive,path.useFolderNames,path.strSettings,path.noUpdate,path.exclude from path where path.idPath=%i",idPath); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); } int iFound = 1; @@ -6621,7 +6654,7 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe iFound++; std::string strSQL=PrepareSQL("select path.strContent,path.strScraper,path.scanRecursive,path.useFolderNames,path.strSettings,path.noUpdate, path.exclude from path where strPath='%s'",strParent.c_str()); - m_pDS->query(strSQL.c_str()); + m_pDS->query(strSQL); CONTENT_TYPE content = CONTENT_NONE; if (!m_pDS->eof()) @@ -6717,7 +6750,7 @@ std::string CVideoDatabase::GetContentForPath(const std::string& strPath) else sql += PrepareSQL("WHERE strPath LIKE '%s%%'", strPath.c_str()); - m_pDS->query( sql.c_str() ); + m_pDS->query( sql ); if (m_pDS->num_rows() && m_pDS->fv(0).get_asInt() > 0) return "episodes"; return foundDirectly ? "tvshows" : "seasons"; @@ -6740,7 +6773,7 @@ void CVideoDatabase::GetMovieGenresByName(const std::string& strSearch, CFileIte strSQL=PrepareSQL("SELECT genre.genre_id, genre.name, path.strPath FROM genre INNER JOIN genre_link ON genre_link.genre_id = genre.genre_id INNER JOIN movie ON (genre_link.media_type='movie' = genre_link.media_id=movie.idMovie) INNER JOIN files ON files.idFile=movie.idFile INNER JOIN path ON path.idPath=files.idPath WHERE genre.name LIKE '%%%s%%'",strSearch.c_str()); else strSQL=PrepareSQL("SELECT DISTINCT genre.genre_id, genre.name FROM genre INNER JOIN genre_link ON genre_link.genre_id=genre.genre_id WHERE genre_link.media_type='movie' AND name LIKE '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -6780,7 +6813,7 @@ void CVideoDatabase::GetMovieCountriesByName(const std::string& strSearch, CFile strSQL=PrepareSQL("SELECT country.country_id, country.name, path.strPath FROM country INNER JOIN country_link ON country_link.country_id=country.country_id INNER JOIN movie ON country_link.media_id=movie.idMovie INNER JOIN files ON files.idFile=movie.idFile INNER JOIN path ON path.idPath=files.idPath WHERE country_link.media_type='movie' AND country.name LIKE '%%%s%%'", strSearch.c_str()); else strSQL=PrepareSQL("SELECT DISTINCT country.country_id, country.name FROM country INNER JOIN country_link ON country_link.country_id=country.country_id WHERE country_link.media_type='movie' AND name like '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -6820,7 +6853,7 @@ void CVideoDatabase::GetTvShowGenresByName(const std::string& strSearch, CFileIt strSQL=PrepareSQL("SELECT genre.genre_id, genre.name, path.strPath FROM genre INNER JOIN genre_link ON genre_link.genre_id=genre.genre_id INNER JOIN tvshow ON genre_link.media_id=tvshow.idShow INNER JOIN tvshowlinkpath ON tvshowlinkpath.idShow=tvshow.idShow INNER JOIN path ON path.idPath=tvshowlinkpath.idPath WHERE genre_link.media_type='tvshow' AND genre.name LIKE '%%%s%%'", strSearch.c_str()); else strSQL=PrepareSQL("SELECT DISTINCT genre.genre_id, genre.name FROM genre INNER JOIN genre_link ON genre_link.genre_id=genre.genre_id WHERE genre_link.media_type='tvshow' AND name LIKE '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -6859,7 +6892,7 @@ void CVideoDatabase::GetMovieActorsByName(const std::string& strSearch, CFileIte strSQL=PrepareSQL("SELECT actor.actor_id, actor.name, path.strPath FROM actor INNER JOIN actor_link ON actor_link.actor_id=actor.actor_id INNER JOIN movie ON actor_link.media_id=movie.idMovie INNER JOIN files ON files.idFile=movie.idFile INNER JOIN path ON path.idPath=files.idPath WHERE actor_link.media_type='movie' AND actor.name LIKE '%%%s%%'", strSearch.c_str()); else strSQL=PrepareSQL("SELECT DISTINCT actor.actor_id, actor.name FROM actor INNER JOIN actor_link ON actor_link.actor_id=actor.actor_id INNER JOIN movie ON actor_link.media_id=movie.idMovie WHERE actor_link.media_type='movie' AND actor.name LIKE '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -6898,7 +6931,7 @@ void CVideoDatabase::GetTvShowsActorsByName(const std::string& strSearch, CFileI strSQL=PrepareSQL("SELECT actor.actor_id, actor.name, path.strPath FROM actor INNER JOIN actor_link ON actor_link.actor_id=actor.actor_id INNER JOIN tvshow ON actor_link.media_id=tvshow.idShow INNER JOIN tvshowlinkpath ON tvshowlinkpath.idPath=tvshow.idShow INNER JOIN path ON path.idPath=tvshowlinkpath.idPath WHERE actor_link.media_type='tvshow' AND actor.name LIKE '%%%s%%'", strSearch.c_str()); else strSQL=PrepareSQL("SELECT DISTINCT actor.actor_id, actor.name FROM actor INNER JOIN actor_link ON actor_link.actor_id=actor.actor_id INNER JOIN tvshow ON actor_link.media_id=tvshow.idShow WHERE actor_link.media_type='tvshow' AND actor.name LIKE '%%%s%%'",strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -6940,7 +6973,7 @@ void CVideoDatabase::GetMusicVideoArtistsByName(const std::string& strSearch, CF strSQL=PrepareSQL("SELECT actor.actor_id, actor.name, path.strPath FROM actor INNER JOIN actor_link ON actor_link.actor_id=actor.actor_id INNER JOIN musicvideo ON actor_link.media_id=musicvideo.idMVideo INNER JOIN files ON files.idFile=musicvideo.idFile INNER JOIN path ON path.idPath=files.idPath WHERE actor_link.media_type='musicvideo' "+strLike, strSearch.c_str()); else strSQL=PrepareSQL("SELECT DISTINCT actor.actor_id, actor.name from actor INNER JOIN actor_link ON actor_link.actor_id=actor.actor_id WHERE actor_link.media_type='musicvideo' "+strLike,strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -6979,7 +7012,7 @@ void CVideoDatabase::GetMusicVideoGenresByName(const std::string& strSearch, CFi strSQL=PrepareSQL("SELECT genre.genre_id, genre.name, path.strPath FROM genre INNER JOIN genre_link ON genre_link.genre_id=genre.genre_id INNER JOIN musicvideo ON genre_link.media_id=musicvideo.idMVideo INNER JOIN files ON files.idFile=musicvideo.idFile INNER JOIN path ON path.idPath=files.idPath WHERE genre_link.media_type='musicvideo' AND genre.name LIKE '%%%s%%'", strSearch.c_str()); else strSQL=PrepareSQL("SELECT DISTINCT genre.genre_id, genre.name FROM genre INNER JOIN genre_link ON genre_link.genre_id=genre.genre_id WHERE genre_link.media_type='musicvideo' AND genre.name LIKE '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7027,7 +7060,7 @@ void CVideoDatabase::GetMusicVideoAlbumsByName(const std::string& strSearch, CFi if (!strSearch.empty()) strSQL += PrepareSQL(" WHERE musicvideo.c%02d like '%%%s%%'",VIDEODB_ID_MUSICVIDEO_ALBUM, strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7072,7 +7105,7 @@ void CVideoDatabase::GetMusicVideosByAlbum(const std::string& strSearch, CFileIt strSQL = PrepareSQL("SELECT musicvideo.idMVideo, musicvideo.c%02d,musicvideo.c%02d, path.strPath FROM musicvideo INNER JOIN files ON files.idFile=musicvideo.idFile INNER JOIN path ON path.idPath=files.idPath WHERE musicvideo.c%02d LIKE '%%%s%%'", VIDEODB_ID_MUSICVIDEO_ALBUM, VIDEODB_ID_MUSICVIDEO_TITLE, VIDEODB_ID_MUSICVIDEO_ALBUM, strSearch.c_str()); else strSQL = PrepareSQL("select musicvideo.idMVideo,musicvideo.c%02d,musicvideo.c%02d from musicvideo where musicvideo.c%02d like '%%%s%%'",VIDEODB_ID_MUSICVIDEO_ALBUM,VIDEODB_ID_MUSICVIDEO_TITLE,VIDEODB_ID_MUSICVIDEO_ALBUM,strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7191,7 +7224,7 @@ unsigned int CVideoDatabase::GetMusicVideoIDs(const std::string& strWhere, std:: if (!strWhere.empty()) strSQL += " where " + strWhere; - if (!m_pDS->query(strSQL.c_str())) return 0; + if (!m_pDS->query(strSQL)) return 0; songIDs.clear(); if (m_pDS->num_rows() == 0) { @@ -7229,7 +7262,7 @@ bool CVideoDatabase::GetRandomMusicVideo(CFileItem* item, int& idSong, const std strSQL += PrepareSQL(" order by RANDOM() limit 1"); CLog::Log(LOGDEBUG, "%s query = %s", __FUNCTION__, strSQL.c_str()); // run query - if (!m_pDS->query(strSQL.c_str())) + if (!m_pDS->query(strSQL)) return false; int iRowsFound = m_pDS->num_rows(); if (iRowsFound != 1) @@ -7274,7 +7307,7 @@ int CVideoDatabase::GetMatchingMusicVideo(const std::string& strArtist, const st else strSQL = PrepareSQL("select musicvideo.idMVideo from musicvideo join actor_link on actor_link.media_id=musicvideo.idMVideo AND actor_link.media_type='musicvideo' join actor on actor.actor_id=actor_link.actor_id where musicvideo.c%02d like '%s' and musicvideo.c%02d like '%s' and actor.name like '%s'",VIDEODB_ID_MUSICVIDEO_ALBUM,strAlbum.c_str(),VIDEODB_ID_MUSICVIDEO_TITLE,strTitle.c_str(),strArtist.c_str()); } - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); if (m_pDS->eof()) return -1; @@ -7310,7 +7343,7 @@ void CVideoDatabase::GetMoviesByName(const std::string& strSearch, CFileItemList strSQL = PrepareSQL("SELECT movie.idMovie, movie.c%02d, path.strPath, movie.idSet FROM movie INNER JOIN files ON files.idFile=movie.idFile INNER JOIN path ON path.idPath=files.idPath WHERE movie.c%02d LIKE '%%%s%%'", VIDEODB_ID_TITLE, VIDEODB_ID_TITLE, strSearch.c_str()); else strSQL = PrepareSQL("select movie.idMovie,movie.c%02d, movie.idSet from movie where movie.c%02d like '%%%s%%'",VIDEODB_ID_TITLE,VIDEODB_ID_TITLE,strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7355,7 +7388,7 @@ void CVideoDatabase::GetTvShowsByName(const std::string& strSearch, CFileItemLis strSQL = PrepareSQL("SELECT tvshow.idShow, tvshow.c%02d, path.strPath FROM tvshow INNER JOIN tvshowlinkpath ON tvshowlinkpath.idShow=tvshow.idShow INNER JOIN path ON path.idPath=tvshowlinkpath.idPath WHERE tvshow.c%02d LIKE '%%%s%%'", VIDEODB_ID_TV_TITLE, VIDEODB_ID_TV_TITLE, strSearch.c_str()); else strSQL = PrepareSQL("select tvshow.idShow,tvshow.c%02d from tvshow where tvshow.c%02d like '%%%s%%'",VIDEODB_ID_TV_TITLE,VIDEODB_ID_TV_TITLE,strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7396,7 +7429,7 @@ void CVideoDatabase::GetEpisodesByName(const std::string& strSearch, CFileItemLi strSQL = PrepareSQL("SELECT episode.idEpisode, episode.c%02d, episode.c%02d, episode.idShow, tvshow.c%02d, path.strPath FROM episode INNER JOIN tvshow ON tvshow.idShow=episode.idShow INNER JOIN files ON files.idFile=episode.idFile INNER JOIN path ON path.idPath=files.idPath WHERE episode.c%02d LIKE '%%%s%%'", VIDEODB_ID_EPISODE_TITLE, VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_TV_TITLE, VIDEODB_ID_EPISODE_TITLE, strSearch.c_str()); else strSQL = PrepareSQL("SELECT episode.idEpisode, episode.c%02d, episode.c%02d, episode.idShow, tvshow.c%02d FROM episode INNER JOIN tvshow ON tvshow.idShow=episode.idShow WHERE episode.c%02d like '%%%s%%'", VIDEODB_ID_EPISODE_TITLE, VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_TV_TITLE, VIDEODB_ID_EPISODE_TITLE, strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7439,7 +7472,7 @@ void CVideoDatabase::GetMusicVideosByName(const std::string& strSearch, CFileIte strSQL = PrepareSQL("SELECT musicvideo.idMVideo, musicvideo.c%02d, path.strPath FROM musicvideo INNER JOIN files ON files.idFile=musicvideo.idFile INNER JOIN path ON path.idPath=files.idPath WHERE musicvideo.c%02d LIKE '%%%s%%'", VIDEODB_ID_MUSICVIDEO_TITLE, VIDEODB_ID_MUSICVIDEO_TITLE, strSearch.c_str()); else strSQL = PrepareSQL("select musicvideo.idMVideo,musicvideo.c%02d from musicvideo where musicvideo.c%02d like '%%%s%%'",VIDEODB_ID_MUSICVIDEO_TITLE,VIDEODB_ID_MUSICVIDEO_TITLE,strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7486,7 +7519,7 @@ void CVideoDatabase::GetEpisodesByPlot(const std::string& strSearch, CFileItemLi strSQL = PrepareSQL("SELECT episode.idEpisode, episode.c%02d, episode.c%02d, episode.idShow, tvshow.c%02d, path.strPath FROM episode INNER JOIN tvshow ON tvshow.idShow=episode.idShow INNER JOIN files ON files.idFile=episode.idFile INNER JOIN path ON path.idPath=files.idPath WHERE episode.c%02d LIKE '%%%s%%'", VIDEODB_ID_EPISODE_TITLE, VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_TV_TITLE, VIDEODB_ID_EPISODE_PLOT, strSearch.c_str()); else strSQL = PrepareSQL("SELECT episode.idEpisode, episode.c%02d, episode.c%02d, episode.idShow, tvshow.c%02d FROM episode INNER JOIN tvshow ON tvshow.idShow=episode.idShow WHERE episode.c%02d LIKE '%%%s%%'", VIDEODB_ID_EPISODE_TITLE, VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_TV_TITLE, VIDEODB_ID_EPISODE_PLOT, strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7526,7 +7559,7 @@ void CVideoDatabase::GetMoviesByPlot(const std::string& strSearch, CFileItemList else strSQL = PrepareSQL("SELECT movie.idMovie, movie.c%02d FROM movie WHERE (movie.c%02d LIKE '%%%s%%' OR movie.c%02d LIKE '%%%s%%' OR movie.c%02d LIKE '%%%s%%')", VIDEODB_ID_TITLE, VIDEODB_ID_PLOT, strSearch.c_str(), VIDEODB_ID_PLOTOUTLINE, strSearch.c_str(), VIDEODB_ID_TAGLINE, strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7568,7 +7601,7 @@ void CVideoDatabase::GetMovieDirectorsByName(const std::string& strSearch, CFile else strSQL = PrepareSQL("SELECT DISTINCT director_link.actor_id, actor.name FROM actor INNER JOIN director_link ON director_link.actor_id=actor.actor_id INNER JOIN movie ON director_link.media_id=movie.idMovie WHERE director_link.media_type='movie' AND actor.name like '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7609,7 +7642,7 @@ void CVideoDatabase::GetTvShowsDirectorsByName(const std::string& strSearch, CFi else strSQL = PrepareSQL("SELECT DISTINCT director_link.actor_id, actor.name FROM actor INNER JOIN director_link ON director_link.actor_id=actor.actor_id INNER JOIN tvshow ON director_link.media_id=tvshow.idShow WHERE director_link.media_type='tvshow' AND actor.name LIKE '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7650,7 +7683,7 @@ void CVideoDatabase::GetMusicVideoDirectorsByName(const std::string& strSearch, else strSQL = PrepareSQL("SELECT DISTINCT director_link.actor_id, actor.name FROM actor INNER JOIN director_link ON director_link.actor_id=actor.actor_id INNER JOIN musicvideo ON director_link.media_id=musicvideo.idMVideo WHERE director_link.media_type='musicvideo' AND actor.name LIKE '%%%s%%'", strSearch.c_str()); - m_pDS->query( strSQL.c_str() ); + m_pDS->query( strSQL ); while (!m_pDS->eof()) { @@ -7701,7 +7734,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st sql += PrepareSQL(" AND path.idPath IN (%s)", strPaths.substr(1).c_str()); } - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (m_pDS->num_rows() == 0) return; if (handle) @@ -7817,7 +7850,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st CLog::Log(LOGDEBUG, "%s: Cleaning files table", __FUNCTION__); sql = "DELETE FROM files WHERE idFile IN " + filesToDelete; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } if (!movieIDs.empty()) @@ -7829,7 +7862,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st CLog::Log(LOGDEBUG, "%s: Cleaning movie table", __FUNCTION__); sql = "DELETE FROM movie WHERE idMovie IN " + moviesToDelete; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } if (!episodeIDs.empty()) @@ -7841,7 +7874,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st CLog::Log(LOGDEBUG, "%s: Cleaning episode table", __FUNCTION__); sql = "DELETE FROM episode WHERE idEpisode IN " + episodesToDelete; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } CLog::Log(LOGDEBUG, "%s: Cleaning paths that don't exist and have content set...", __FUNCTION__); @@ -7850,7 +7883,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st "AND (strSettings IS NULL OR strSettings = '') " "AND (strHash IS NULL OR strHash = '') " "AND (exclude IS NULL OR exclude != 1))"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); std::string strIds; while (!m_pDS->eof()) { @@ -7870,16 +7903,16 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st if (!strIds.empty()) { sql = PrepareSQL("DELETE FROM path WHERE idPath IN (%s)", StringUtils::TrimRight(strIds, ",").c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); sql = "DELETE FROM tvshowlinkpath WHERE NOT EXISTS (SELECT 1 FROM path WHERE path.idPath = tvshowlinkpath.idPath)"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } CLog::Log(LOGDEBUG, "%s: Cleaning tvshow table", __FUNCTION__); std::string tvshowsToDelete; sql = "SELECT idShow FROM tvshow WHERE NOT EXISTS (SELECT 1 FROM tvshowlinkpath WHERE tvshowlinkpath.idShow = tvshow.idShow)"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); while (!m_pDS->eof()) { tvshowIDs.push_back(m_pDS->fv(0).get_asInt()); @@ -7890,7 +7923,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st if (!tvshowsToDelete.empty()) { sql = "DELETE FROM tvshow WHERE idShow IN (" + StringUtils::TrimRight(tvshowsToDelete, ",") + ")"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } if (!musicVideoIDs.empty()) @@ -7902,7 +7935,7 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st CLog::Log(LOGDEBUG, "%s: Cleaning musicvideo table", __FUNCTION__); sql = "DELETE FROM musicvideo WHERE idMVideo IN " + musicVideosToDelete; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } CLog::Log(LOGDEBUG, "%s: Cleaning path table", __FUNCTION__); @@ -7918,32 +7951,32 @@ void CVideoDatabase::CleanDatabase(CGUIDialogProgressBarHandle* handle, const st "AND NOT EXISTS (SELECT 1 FROM episode WHERE episode.c%02d = path.idPath) " "AND NOT EXISTS (SELECT 1 FROM musicvideo WHERE musicvideo.c%02d = path.idPath)" , VIDEODB_ID_PARENTPATHID, VIDEODB_ID_EPISODE_PARENTPATHID, VIDEODB_ID_MUSICVIDEO_PARENTPATHID ); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CLog::Log(LOGDEBUG, "%s: Cleaning genre table", __FUNCTION__); sql = "DELETE FROM genre " "WHERE NOT EXISTS (SELECT 1 FROM genre_link WHERE genre_link.genre_id = genre.genre_id)"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CLog::Log(LOGDEBUG, "%s: Cleaning country table", __FUNCTION__); sql = "DELETE FROM country WHERE NOT EXISTS (SELECT 1 FROM country_link WHERE country_link.country_id = country.country_id)"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CLog::Log(LOGDEBUG, "%s: Cleaning actor table of actors, directors and writers", __FUNCTION__); sql = "DELETE FROM actor " "WHERE NOT EXISTS (SELECT 1 FROM actor_link WHERE actor_link.actor_id = actor.actor_id) " "AND NOT EXISTS (SELECT 1 FROM director_link WHERE director_link.actor_id = actor.actor_id) " "AND NOT EXISTS (SELECT 1 FROM writer_link WHERE writer_link.actor_id = actor.actor_id)"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CLog::Log(LOGDEBUG, "%s: Cleaning studio table", __FUNCTION__); sql = "DELETE FROM studio " "WHERE NOT EXISTS (SELECT 1 FROM studio_link WHERE studio_link.studio_id = studio.studio_id)"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CLog::Log(LOGDEBUG, "%s: Cleaning set table", __FUNCTION__); sql = "DELETE FROM sets WHERE NOT EXISTS (SELECT 1 FROM movie WHERE movie.idSet = sets.idSet)"; - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); CommitTransaction(); @@ -8030,7 +8063,7 @@ std::vector<int> CVideoDatabase::CleanMediaType(const std::string &mediaType, co // map of parent path ID to boolean pair (if not exists and user choice) std::map<int, std::pair<bool, bool> > sourcePathsDeleteDecisions; - m_pDS2->query(sql.c_str()); + m_pDS2->query(sql); while (!m_pDS2->eof()) { bool del = true; @@ -8149,7 +8182,7 @@ void CVideoDatabase::DumpToDummyFiles(const std::string &path) } } -void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = false */, bool images /* = false */, bool actorThumbs /* false */, bool overwrite /*=false*/) +void CVideoDatabase::ExportToXML(const std::string &path, bool singleFile /* = true */, bool images /* = false */, bool actorThumbs /* false */, bool overwrite /*=false*/) { int iFailCount = 0; CGUIDialogProgress *progress=NULL; @@ -8175,7 +8208,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = std::string moviesDir = URIUtils::AddFileToFolder(exportRoot, "movies"); std::string musicvideosDir = URIUtils::AddFileToFolder(exportRoot, "musicvideos"); std::string tvshowsDir = URIUtils::AddFileToFolder(exportRoot, "tvshows"); - if (!singleFiles) + if (singleFile) { images = true; overwrite = false; @@ -8192,7 +8225,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = // find all movies std::string sql = "select * from movie_view"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (progress) { @@ -8213,7 +8246,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = TiXmlDeclaration decl("1.0", "UTF-8", "yes"); xmlDoc.InsertEndChild(decl); TiXmlNode *pMain = NULL; - if (singleFiles) + if (!singleFile) pMain = &xmlDoc; else { @@ -8229,7 +8262,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = if (StringUtils::StartsWith(movie.m_strTrailer, movie.m_strPath)) movie.m_strTrailer = movie.m_strTrailer.substr(movie.m_strPath.size()); std::map<std::string, std::string> artwork; - if (GetArtForItem(movie.m_iDbId, movie.m_type, artwork) && !singleFiles) + if (GetArtForItem(movie.m_iDbId, movie.m_type, artwork) && singleFile) { TiXmlElement additionalNode("art"); for (std::map<std::string, std::string>::const_iterator i = artwork.begin(); i != artwork.end(); ++i) @@ -8237,7 +8270,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = movie.Save(pMain, "movie", true, &additionalNode); } else - movie.Save(pMain, "movie", !singleFiles); + movie.Save(pMain, "movie", singleFile); // reset old skip state bool bSkip = false; @@ -8256,7 +8289,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } CFileItem item(movie.m_strFileNameAndPath,false); - if (singleFiles && CUtil::SupportsWriteFileOperations(movie.m_strFileNameAndPath)) + if (!singleFile && CUtil::SupportsWriteFileOperations(movie.m_strFileNameAndPath)) { if (!item.Exists(false)) { @@ -8285,7 +8318,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } } } - if (singleFiles) + if (!singleFile) { xmlDoc.Clear(); TiXmlDeclaration decl("1.0", "UTF-8", "yes"); @@ -8294,7 +8327,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = if (images && !bSkip) { - if (!singleFiles) + if (singleFile) { std::string strFileName(movie.m_strTitle); if (movie.m_iYear > 0) @@ -8307,7 +8340,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = CTextureCache::GetInstance().Export(i->second, savedThumb, overwrite); } if (actorThumbs) - ExportActorThumbs(actorsDir, movie, singleFiles, overwrite); + ExportActorThumbs(actorsDir, movie, !singleFile, overwrite); } m_pDS->next(); current++; @@ -8317,7 +8350,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = // find all musicvideos sql = "select * from musicvideo_view"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); total = m_pDS->num_rows(); current = 0; @@ -8326,7 +8359,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = { CVideoInfoTag movie = GetDetailsForMusicVideo(m_pDS, true); std::map<std::string, std::string> artwork; - if (GetArtForItem(movie.m_iDbId, movie.m_type, artwork) && !singleFiles) + if (GetArtForItem(movie.m_iDbId, movie.m_type, artwork) && singleFile) { TiXmlElement additionalNode("art"); for (std::map<std::string, std::string>::const_iterator i = artwork.begin(); i != artwork.end(); ++i) @@ -8334,7 +8367,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = movie.Save(pMain, "musicvideo", true, &additionalNode); } else - movie.Save(pMain, "musicvideo", !singleFiles); + movie.Save(pMain, "musicvideo", singleFile); // reset old skip state bool bSkip = false; @@ -8353,7 +8386,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } CFileItem item(movie.m_strFileNameAndPath,false); - if (singleFiles && CUtil::SupportsWriteFileOperations(movie.m_strFileNameAndPath)) + if (!singleFile && CUtil::SupportsWriteFileOperations(movie.m_strFileNameAndPath)) { if (!item.Exists(false)) { @@ -8375,7 +8408,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } } } - if (singleFiles) + if (!singleFile) { xmlDoc.Clear(); TiXmlDeclaration decl("1.0", "UTF-8", "yes"); @@ -8383,7 +8416,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } if (images && !bSkip) { - if (!singleFiles) + if (singleFile) { std::string strFileName(StringUtils::Join(movie.m_artist, g_advancedSettings.m_videoItemSeparator) + "." + movie.m_strTitle); if (movie.m_iYear > 0) @@ -8403,7 +8436,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = // repeat for all tvshows sql = "SELECT * FROM tvshow_view"; - m_pDS->query(sql.c_str()); + m_pDS->query(sql); total = m_pDS->num_rows(); current = 0; @@ -8416,7 +8449,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = GetTvShowSeasonArt(tvshow.m_iDbId, seasonArt); std::map<std::string, std::string> artwork; - if (GetArtForItem(tvshow.m_iDbId, tvshow.m_type, artwork) && !singleFiles) + if (GetArtForItem(tvshow.m_iDbId, tvshow.m_type, artwork) && singleFile) { TiXmlElement additionalNode("art"); for (std::map<std::string, std::string>::const_iterator i = artwork.begin(); i != artwork.end(); ++i) @@ -8432,7 +8465,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = tvshow.Save(pMain, "tvshow", true, &additionalNode); } else - tvshow.Save(pMain, "tvshow", !singleFiles); + tvshow.Save(pMain, "tvshow", singleFile); // reset old skip state bool bSkip = false; @@ -8451,7 +8484,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } CFileItem item(tvshow.m_strPath, true); - if (singleFiles && CUtil::SupportsWriteFileOperations(tvshow.m_strPath)) + if (!singleFile && CUtil::SupportsWriteFileOperations(tvshow.m_strPath)) { if (!item.Exists(false)) { @@ -8473,7 +8506,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } } } - if (singleFiles) + if (!singleFile) { xmlDoc.Clear(); TiXmlDeclaration decl("1.0", "UTF-8", "yes"); @@ -8481,7 +8514,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } if (images && !bSkip) { - if (!singleFiles) + if (singleFile) item.SetPath(GetSafeFile(tvshowsDir, tvshow.m_strTitle)); for (std::map<std::string, std::string>::const_iterator i = artwork.begin(); i != artwork.end(); ++i) @@ -8491,7 +8524,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } if (actorThumbs) - ExportActorThumbs(actorsDir, tvshow, singleFiles, overwrite); + ExportActorThumbs(actorsDir, tvshow, !singleFile, overwrite); // export season thumbs for (std::map<int, std::map<std::string, std::string> >::const_iterator i = seasonArt.begin(); i != seasonArt.end(); ++i) @@ -8514,31 +8547,31 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = // now save the episodes from this show sql = PrepareSQL("select * from episode_view where idShow=%i order by strFileName, idEpisode",tvshow.m_iDbId); - pDS->query(sql.c_str()); + pDS->query(sql); std::string showDir(item.GetPath()); while (!pDS->eof()) { CVideoInfoTag episode = GetDetailsForEpisode(pDS, true); std::map<std::string, std::string> artwork; - if (GetArtForItem(episode.m_iDbId, MediaTypeEpisode, artwork) && !singleFiles) + if (GetArtForItem(episode.m_iDbId, MediaTypeEpisode, artwork) && singleFile) { TiXmlElement additionalNode("art"); for (std::map<std::string, std::string>::const_iterator i = artwork.begin(); i != artwork.end(); ++i) XMLUtils::SetString(&additionalNode, i->first.c_str(), i->second); episode.Save(pMain->LastChild(), "episodedetails", true, &additionalNode); } - else if (!singleFiles) - episode.Save(pMain->LastChild(), "episodedetails", !singleFiles); + else if (singleFile) + episode.Save(pMain->LastChild(), "episodedetails", singleFile); else - episode.Save(pMain, "episodedetails", !singleFiles); + episode.Save(pMain, "episodedetails", singleFile); pDS->next(); // multi-episode files need dumping to the same XML - while (singleFiles && !pDS->eof() && + while (!singleFile && !pDS->eof() && episode.m_iFileId == pDS->fv("idFile").get_asInt()) { episode = GetDetailsForEpisode(pDS, true); - episode.Save(pMain, "episodedetails", !singleFiles); + episode.Save(pMain, "episodedetails", singleFile); pDS->next(); } @@ -8546,7 +8579,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = bool bSkip = false; CFileItem item(episode.m_strFileNameAndPath, false); - if (singleFiles && CUtil::SupportsWriteFileOperations(episode.m_strFileNameAndPath)) + if (!singleFile && CUtil::SupportsWriteFileOperations(episode.m_strFileNameAndPath)) { if (!item.Exists(false)) { @@ -8568,7 +8601,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } } } - if (singleFiles) + if (!singleFile) { xmlDoc.Clear(); TiXmlDeclaration decl("1.0", "UTF-8", "yes"); @@ -8577,7 +8610,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = if (images && !bSkip) { - if (!singleFiles) + if (singleFile) { std::string epName = StringUtils::Format("s%02ie%02i.avi", episode.m_iSeason, episode.m_iEpisode); item.SetPath(URIUtils::AddFileToFolder(showDir, epName)); @@ -8588,7 +8621,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = CTextureCache::GetInstance().Export(i->second, savedThumb, overwrite); } if (actorThumbs) - ExportActorThumbs(actorsDir, episode, singleFiles, overwrite); + ExportActorThumbs(actorsDir, episode, !singleFile, overwrite); } } pDS->close(); @@ -8597,13 +8630,13 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = } m_pDS->close(); - if (singleFiles && progress) + if (!singleFile && progress) { progress->SetPercentage(100); progress->Progress(); } - if (!singleFiles) + if (singleFile) { // now dump path info std::set<std::string> paths; @@ -8629,7 +8662,7 @@ void CVideoDatabase::ExportToXML(const std::string &path, bool singleFiles /* = xmlDoc.SaveFile(xmlFile); } CVariant data; - if (!singleFiles) + if (singleFile) { data["root"] = exportRoot; data["file"] = xmlFile; @@ -8991,7 +9024,7 @@ bool CVideoDatabase::SetSingleValue(const std::string &table, const std::string sql = PrepareSQL("UPDATE %s SET %s='%s'", table.c_str(), fieldName.c_str(), strValue.c_str()); if (!conditionName.empty()) sql += PrepareSQL(" WHERE %s=%u", conditionName.c_str(), conditionValue); - if (m_pDS->exec(sql.c_str()) == 0) + if (m_pDS->exec(sql) == 0) return true; } catch (...) @@ -9339,7 +9372,7 @@ bool CVideoDatabase::SetVideoUserRating(int dbId, int rating, const MediaType& m else if (mediaType == MediaTypeTvShow) sql = PrepareSQL("UPDATE tvshow SET userrating=%i WHERE idShow = %i", rating, dbId); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); return true; } catch (...) diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h index 68aa18f8ba..b985f287e0 100644 --- a/xbmc/video/VideoDatabase.h +++ b/xbmc/video/VideoDatabase.h @@ -18,15 +18,17 @@ * <http://www.gnu.org/licenses/>. * */ -#include "dbwrappers/Database.h" -#include "VideoInfoTag.h" + +#include <memory> +#include <set> +#include <utility> + #include "addons/Scraper.h" #include "Bookmark.h" +#include "dbwrappers/Database.h" #include "utils/SortUtils.h" #include "video/VideoDbUrl.h" - -#include <memory> -#include <set> +#include "VideoInfoTag.h" class CFileItem; class CFileItemList; @@ -73,13 +75,14 @@ namespace VIDEO #define VIDEODB_DETAILS_MOVIE_SET_ID VIDEODB_MAX_COLUMNS + 2 #define VIDEODB_DETAILS_MOVIE_USER_RATING VIDEODB_MAX_COLUMNS + 3 #define VIDEODB_DETAILS_MOVIE_SET_NAME VIDEODB_MAX_COLUMNS + 4 -#define VIDEODB_DETAILS_MOVIE_FILE VIDEODB_MAX_COLUMNS + 5 -#define VIDEODB_DETAILS_MOVIE_PATH VIDEODB_MAX_COLUMNS + 6 -#define VIDEODB_DETAILS_MOVIE_PLAYCOUNT VIDEODB_MAX_COLUMNS + 7 -#define VIDEODB_DETAILS_MOVIE_LASTPLAYED VIDEODB_MAX_COLUMNS + 8 -#define VIDEODB_DETAILS_MOVIE_DATEADDED VIDEODB_MAX_COLUMNS + 9 -#define VIDEODB_DETAILS_MOVIE_RESUME_TIME VIDEODB_MAX_COLUMNS + 10 -#define VIDEODB_DETAILS_MOVIE_TOTAL_TIME VIDEODB_MAX_COLUMNS + 11 +#define VIDEODB_DETAILS_MOVIE_SET_OVERVIEW VIDEODB_MAX_COLUMNS + 5 +#define VIDEODB_DETAILS_MOVIE_FILE VIDEODB_MAX_COLUMNS + 6 +#define VIDEODB_DETAILS_MOVIE_PATH VIDEODB_MAX_COLUMNS + 7 +#define VIDEODB_DETAILS_MOVIE_PLAYCOUNT VIDEODB_MAX_COLUMNS + 8 +#define VIDEODB_DETAILS_MOVIE_LASTPLAYED VIDEODB_MAX_COLUMNS + 9 +#define VIDEODB_DETAILS_MOVIE_DATEADDED VIDEODB_MAX_COLUMNS + 10 +#define VIDEODB_DETAILS_MOVIE_RESUME_TIME VIDEODB_MAX_COLUMNS + 11 +#define VIDEODB_DETAILS_MOVIE_TOTAL_TIME VIDEODB_MAX_COLUMNS + 12 #define VIDEODB_DETAILS_EPISODE_TVSHOW_ID VIDEODB_MAX_COLUMNS + 2 #define VIDEODB_DETAILS_EPISODE_USER_RATING VIDEODB_MAX_COLUMNS + 3 @@ -729,7 +732,7 @@ public: */ void UpdateFileDateAdded(int idFile, const std::string& strFileNameAndPath); - void ExportToXML(const std::string &path, bool singleFiles = false, bool images=false, bool actorThumbs=false, bool overwrite=false); + void ExportToXML(const std::string &path, bool singleFile = true, bool images=false, bool actorThumbs=false, bool overwrite=false); void ExportActorThumbs(const std::string &path, const CVideoInfoTag& tag, bool singleFiles, bool overwrite=false); void ImportFromXML(const std::string &path); void DumpToDummyFiles(const std::string &path); @@ -795,7 +798,7 @@ public: virtual bool GetFilter(CDbUrl &videoUrl, Filter &filter, SortDescription &sorting); int AddSeason(int showID, int season); - int AddSet(const std::string& strSet); + int AddSet(const std::string& strSet, const std::string& strOverview = ""); void ClearMovieSet(int idMovie); void SetMovieSet(int idMovie, int idSet); bool SetVideoUserRating(int dbId, int rating, const MediaType& mediaType); diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp index 7a55af74ed..736c346f55 100644 --- a/xbmc/video/VideoInfoScanner.cpp +++ b/xbmc/video/VideoInfoScanner.cpp @@ -18,40 +18,43 @@ * */ -#include "threads/SystemClock.h" -#include "FileItem.h" #include "VideoInfoScanner.h" + +#include <utility> + +#include "dialogs/GUIDialogExtendedProgressBar.h" +#include "dialogs/GUIDialogOK.h" +#include "dialogs/GUIDialogProgress.h" #include "events/EventLog.h" #include "events/MediaLibraryEvent.h" +#include "FileItem.h" #include "filesystem/DirectoryCache.h" -#include "Util.h" -#include "NfoFile.h" -#include "utils/RegExp.h" -#include "utils/md5.h" +#include "filesystem/File.h" #include "filesystem/MultiPathDirectory.h" #include "filesystem/StackDirectory.h" -#include "VideoInfoDownloader.h" #include "GUIInfoManager.h" -#include "filesystem/File.h" -#include "dialogs/GUIDialogExtendedProgressBar.h" -#include "dialogs/GUIDialogProgress.h" -#include "dialogs/GUIDialogOK.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "GUIUserMessages.h" #include "interfaces/AnnouncementManager.h" #include "messaging/ApplicationMessenger.h" #include "messaging/helpers/DialogHelper.h" +#include "NfoFile.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" -#include "utils/StringUtils.h" -#include "guilib/LocalizeStrings.h" -#include "guilib/GUIWindowManager.h" +#include "TextureCache.h" +#include "threads/SystemClock.h" +#include "URL.h" +#include "Util.h" #include "utils/log.h" +#include "utils/md5.h" +#include "utils/RegExp.h" +#include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" #include "video/VideoLibraryQueue.h" #include "video/VideoThumbLoader.h" -#include "TextureCache.h" -#include "GUIUserMessages.h" -#include "URL.h" +#include "VideoInfoDownloader.h" using namespace XFILE; using namespace ADDON; diff --git a/xbmc/video/VideoInfoTag.cpp b/xbmc/video/VideoInfoTag.cpp index 0781e655f1..0a5c21f6b6 100644 --- a/xbmc/video/VideoInfoTag.cpp +++ b/xbmc/video/VideoInfoTag.cpp @@ -51,6 +51,7 @@ void CVideoInfoTag::Reset() m_cast.clear(); m_strSet.clear(); m_iSetId = -1; + m_strSetOverview.clear(); m_tags.clear(); m_strFile.clear(); m_strPath.clear(); @@ -175,7 +176,14 @@ bool CVideoInfoTag::Save(TiXmlNode *node, const std::string &tag, bool savePathI XMLUtils::SetString(movie, "id", m_strIMDBNumber); XMLUtils::SetStringArray(movie, "genre", m_genre); XMLUtils::SetStringArray(movie, "country", m_country); - XMLUtils::SetString(movie, "set", m_strSet); + if (!m_strSet.empty()) + { + TiXmlElement set("set"); + XMLUtils::SetString(&set, "name", m_strSet); + if (!m_strSetOverview.empty()) + XMLUtils::SetString(&set, "overview", m_strSetOverview); + movie->InsertEndChild(set); + } XMLUtils::SetStringArray(movie, "tag", m_tags); XMLUtils::SetStringArray(movie, "credits", m_writingCredits); XMLUtils::SetStringArray(movie, "director", m_director); @@ -288,6 +296,7 @@ void CVideoInfoTag::Archive(CArchive& ar) ar << m_strSet; ar << m_iSetId; + ar << m_strSetOverview; ar << m_tags; ar << m_duration; ar << m_strFile; @@ -366,6 +375,7 @@ void CVideoInfoTag::Archive(CArchive& ar) ar >> m_strSet; ar >> m_iSetId; + ar >> m_strSetOverview; ar >> m_tags; ar >> m_duration; ar >> m_strFile; @@ -440,6 +450,7 @@ void CVideoInfoTag::Serialize(CVariant& value) const } value["set"] = m_strSet; value["setid"] = m_iSetId; + value["setoverview"] = m_strSetOverview; value["tag"] = m_tags; value["runtime"] = GetDuration(); value["file"] = m_strFile; @@ -746,8 +757,23 @@ void CVideoInfoTag::ParseNative(const TiXmlElement* movie, bool prioritise) node = node->NextSiblingElement("actor"); } + // Pre-Jarvis NFO file: + // <set>A set</set> if (XMLUtils::GetString(movie, "set", value)) SetSet(value); + // Jarvis+: + // <set><name>A set</name><overview>A set with a number of movies...</overview></set> + node = movie->FirstChildElement("set"); + if (node) + { + // No name, no set + if (XMLUtils::GetString(node, "name", value)) + { + SetSet(value); + if (XMLUtils::GetString(node, "overview", value)) + SetSetOverview(value); + } + } std::vector<std::string> tags(m_tags); if (XMLUtils::GetStringArray(movie, "tag", tags, prioritise, g_advancedSettings.m_videoItemSeparator)) @@ -987,6 +1013,11 @@ void CVideoInfoTag::SetSet(std::string set) m_strSet = Trim(std::move(set)); } +void CVideoInfoTag::SetSetOverview(std::string setOverview) +{ + m_strSetOverview = Trim(std::move(setOverview)); +} + void CVideoInfoTag::SetTags(std::vector<std::string> tags) { m_tags = Trim(std::move(tags)); diff --git a/xbmc/video/VideoInfoTag.h b/xbmc/video/VideoInfoTag.h index 65de578e85..0ac3e78b83 100644 --- a/xbmc/video/VideoInfoTag.h +++ b/xbmc/video/VideoInfoTag.h @@ -109,6 +109,7 @@ public: void SetVotes(std::string votes); void SetArtist(std::vector<std::string> artist); void SetSet(std::string set); + void SetSetOverview(std::string setOverview); void SetTags(std::vector<std::string> tags); void SetFile(std::string file); void SetPath(std::string path); @@ -145,6 +146,7 @@ public: typedef std::vector< SActorInfo >::const_iterator iCast; std::string m_strSet; int m_iSetId; + std::string m_strSetOverview; std::vector<std::string> m_tags; std::string m_strFile; std::string m_strPath; diff --git a/xbmc/video/VideoLibraryQueue.cpp b/xbmc/video/VideoLibraryQueue.cpp index 628e0c7503..aacc1ea577 100644 --- a/xbmc/video/VideoLibraryQueue.cpp +++ b/xbmc/video/VideoLibraryQueue.cpp @@ -19,16 +19,19 @@ */ #include "VideoLibraryQueue.h" -#include "GUIUserMessages.h" -#include "Util.h" + +#include <utility> + #include "guilib/GUIWindowManager.h" +#include "GUIUserMessages.h" #include "threads/SingleLock.h" -#include "video/VideoDatabase.h" +#include "Util.h" #include "video/jobs/VideoLibraryCleaningJob.h" #include "video/jobs/VideoLibraryJob.h" #include "video/jobs/VideoLibraryMarkWatchedJob.h" #include "video/jobs/VideoLibraryRefreshingJob.h" #include "video/jobs/VideoLibraryScanningJob.h" +#include "video/VideoDatabase.h" CVideoLibraryQueue::CVideoLibraryQueue() : CJobQueue(false, 1, CJob::PRIORITY_LOW), diff --git a/xbmc/video/VideoThumbLoader.cpp b/xbmc/video/VideoThumbLoader.cpp index 798476ca7b..20071360d7 100644 --- a/xbmc/video/VideoThumbLoader.cpp +++ b/xbmc/video/VideoThumbLoader.cpp @@ -18,28 +18,30 @@ * */ +#include "VideoThumbLoader.h" + #include <cstdlib> +#include <utility> -#include "VideoThumbLoader.h" -#include "filesystem/StackDirectory.h" -#include "utils/URIUtils.h" -#include "URL.h" -#include "filesystem/DirectoryCache.h" +#include "cores/dvdplayer/DVDFileInfo.h" #include "FileItem.h" -#include "settings/Settings.h" -#include "settings/VideoSettings.h" -#include "GUIUserMessages.h" +#include "filesystem/DirectoryCache.h" +#include "filesystem/StackDirectory.h" #include "guilib/GUIWindowManager.h" #include "guilib/StereoscopicsManager.h" +#include "GUIUserMessages.h" +#include "music/MusicDatabase.h" #include "rendering/RenderSystem.h" +#include "settings/AdvancedSettings.h" +#include "settings/Settings.h" +#include "settings/VideoSettings.h" #include "TextureCache.h" +#include "URL.h" #include "utils/log.h" -#include "video/VideoInfoTag.h" -#include "video/VideoDatabase.h" -#include "cores/dvdplayer/DVDFileInfo.h" -#include "music/MusicDatabase.h" #include "utils/StringUtils.h" -#include "settings/AdvancedSettings.h" +#include "utils/URIUtils.h" +#include "video/VideoDatabase.h" +#include "video/VideoInfoTag.h" using namespace XFILE; using namespace VIDEO; diff --git a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp index 6dcdd7ef3d..8d57767555 100644 --- a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp +++ b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp @@ -19,33 +19,35 @@ */ #include "GUIDialogAudioSubtitleSettings.h" -#include "Application.h" -#include "FileItem.h" -#include "GUIPassword.h" -#include "URL.h" + +#include <string> +#include <vector> + #include "addons/Skin.h" -#include "cores/IPlayer.h" +#include "Application.h" #include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/IPlayer.h" #include "dialogs/GUIDialogFileBrowser.h" #include "dialogs/GUIDialogYesNo.h" +#include "FileItem.h" #include "filesystem/File.h" -#include "guilib/LocalizeStrings.h" #include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "GUIPassword.h" #include "profiles/ProfilesManager.h" #include "settings/AdvancedSettings.h" +#include "settings/lib/Setting.h" +#include "settings/lib/SettingsManager.h" #include "settings/MediaSettings.h" #include "settings/MediaSourceSettings.h" #include "settings/Settings.h" -#include "settings/lib/Setting.h" -#include "settings/lib/SettingsManager.h" +#include "URL.h" #include "utils/LangCodeExpander.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" #include "video/VideoDatabase.h" -#include <string> -#include <vector> #define SETTING_AUDIO_VOLUME "audio.volume" #define SETTING_AUDIO_VOLUME_AMPLIFICATION "audio.volumeamplification" diff --git a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.h b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.h index 2fd3a20bc4..b27cba7cfa 100644 --- a/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.h +++ b/xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.h @@ -20,6 +20,8 @@ * */ +#include <utility> + #include "settings/dialogs/GUIDialogSettingsManualBase.h" class CVariant; diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp index 7ae64c7c1c..b24856632a 100644 --- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp @@ -18,23 +18,27 @@ * */ -#include "system.h" #include "GUIDialogVideoSettings.h" -#include "GUIPassword.h" + +#include <utility> + #include "addons/Skin.h" -#ifdef HAS_VIDEO_PLAYBACK -#include "cores/VideoRenderers/RenderManager.h" -#endif #include "dialogs/GUIDialogYesNo.h" #include "guilib/GUIWindowManager.h" +#include "GUIPassword.h" #include "profiles/ProfilesManager.h" -#include "settings/MediaSettings.h" -#include "settings/Settings.h" #include "settings/lib/Setting.h" #include "settings/lib/SettingsManager.h" +#include "settings/MediaSettings.h" +#include "settings/Settings.h" +#include "system.h" #include "utils/log.h" -#include "video/VideoDatabase.h" #include "utils/Variant.h" +#include "video/VideoDatabase.h" + +#ifdef HAS_VIDEO_PLAYBACK +#include "cores/VideoRenderers/RenderManager.h" +#endif #define SETTING_VIDEO_VIEW_MODE "video.viewmode" #define SETTING_VIDEO_ZOOM "video.zoom" diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp index e7a69dc630..5a391ef3f2 100644 --- a/xbmc/video/windows/GUIWindowVideoBase.cpp +++ b/xbmc/video/windows/GUIWindowVideoBase.cpp @@ -1400,7 +1400,8 @@ void CGUIWindowVideoBase::GetGroupedItems(CFileItemList &items) (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOLIBRARY_GROUPMOVIESETS) || (StringUtils::EqualsNoCase(group, "sets") && mixed))) { CFileItemList groupedItems; - if (GroupUtils::Group(GroupBySet, m_strFilterPath, items, groupedItems, GroupAttributeIgnoreSingleItems)) + GroupAttribute groupAttributes = CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOLIBRARY_GROUPSINGLEITEMSETS) ? GroupAttributeNone : GroupAttributeIgnoreSingleItems; + if (GroupUtils::GroupAndMix(GroupBySet, m_strFilterPath, items, groupedItems, groupAttributes)) { items.ClearItems(); items.Append(groupedItems); @@ -1710,10 +1711,9 @@ void CGUIWindowVideoBase::OnAssignContent(const std::string &path) if (OnUnAssignContent(path, 20442, 20443)) bScan = true; } + db.SetScraperForPath(path, info, settings); } - db.SetScraperForPath(path,info,settings); - if (bScan) { g_application.StartVideoScan(path, true, true); diff --git a/xbmc/video/windows/GUIWindowVideoNav.cpp b/xbmc/video/windows/GUIWindowVideoNav.cpp index ae6562f39f..e46bc854ae 100644 --- a/xbmc/video/windows/GUIWindowVideoNav.cpp +++ b/xbmc/video/windows/GUIWindowVideoNav.cpp @@ -466,6 +466,8 @@ bool CGUIWindowVideoNav::GetDirectory(const std::string &strDirectory, CFileItem else items.SetContent(""); } + else if (URIUtils::PathEquals(items.GetPath(), "special://videoplaylists/")) + items.SetContent("playlists"); else if (!items.IsVirtualDirectoryRoot()) { // load info from the database std::string label; diff --git a/xbmc/view/GUIViewControl.cpp b/xbmc/view/GUIViewControl.cpp index 750ee71da2..2a3c9495c3 100644 --- a/xbmc/view/GUIViewControl.cpp +++ b/xbmc/view/GUIViewControl.cpp @@ -19,14 +19,17 @@ */ #include "GUIViewControl.h" -#include "guilib/GUIWindowManager.h" -#include "utils/URIUtils.h" -#include "utils/StringUtils.h" + +#include <utility> + #include "FileItem.h" -#include "guilib/LocalizeStrings.h" #include "GUIInfoManager.h" -#include "guilib/WindowIDs.h" +#include "guilib/GUIWindowManager.h" #include "guilib/IGUIContainer.h" +#include "guilib/LocalizeStrings.h" +#include "guilib/WindowIDs.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" CGUIViewControl::CGUIViewControl(void) { diff --git a/xbmc/view/ViewDatabase.cpp b/xbmc/view/ViewDatabase.cpp index bdd5376508..f6821d30d1 100644 --- a/xbmc/view/ViewDatabase.cpp +++ b/xbmc/view/ViewDatabase.cpp @@ -19,18 +19,22 @@ */ #include "ViewDatabase.h" -#include "utils/URIUtils.h" -#include "view/ViewState.h" + +#include <utility> + +#include "dbwrappers/dataset.h" +#include "SortFileItem.h" +#include "system.h" #include "utils/LegacyPathTranslation.h" #include "utils/log.h" #include "utils/SortUtils.h" #include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include "view/ViewState.h" + #ifdef TARGET_POSIX #include "linux/ConvUtils.h" // GetLastError() #endif -#include "dbwrappers/dataset.h" -#include "SortFileItem.h" - CViewDatabase::CViewDatabase(void) { } @@ -89,7 +93,7 @@ void CViewDatabase::UpdateTables(int version) m_pDS->close(); for (std::vector< std::pair<int, std::string> >::const_iterator it = paths.begin(); it != paths.end(); ++it) - m_pDS->exec(PrepareSQL("UPDATE view SET path='%s' WHERE idView=%d", it->second.c_str(), it->first).c_str()); + m_pDS->exec(PrepareSQL("UPDATE view SET path='%s' WHERE idView=%d", it->second.c_str(), it->first)); } } if (version < 6) @@ -140,7 +144,7 @@ bool CViewDatabase::GetViewState(const std::string &path, int window, CViewState sql = PrepareSQL("select * from view where window = %i and path='%s'", window, path1.c_str()); else sql = PrepareSQL("select * from view where window = %i and path='%s' and skin='%s'", window, path1.c_str(), skin.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // have some information @@ -172,21 +176,21 @@ bool CViewDatabase::SetViewState(const std::string &path, int window, const CVie if (path1.empty()) path1 = "root://"; std::string sql = PrepareSQL("select idView from view where window = %i and path='%s' and skin='%s'", window, path1.c_str(), skin.c_str()); - m_pDS->query(sql.c_str()); + m_pDS->query(sql); if (!m_pDS->eof()) { // update the view int idView = m_pDS->fv("idView").get_asInt(); m_pDS->close(); sql = PrepareSQL("update view set viewMode=%i,sortMethod=%i,sortOrder=%i,sortAttributes=%i where idView=%i", state.m_viewMode, (int)state.m_sortDescription.sortBy, (int)state.m_sortDescription.sortOrder, (int)state.m_sortDescription.sortAttributes, idView); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } else { // add the view m_pDS->close(); sql = PrepareSQL("insert into view (idView, path, window, viewMode, sortMethod, sortOrder, sortAttributes, skin) values(NULL, '%s', %i, %i, %i, %i, %i, '%s')", path1.c_str(), window, state.m_viewMode, (int)state.m_sortDescription.sortBy, (int)state.m_sortDescription.sortOrder, (int)state.m_sortDescription.sortAttributes, skin.c_str()); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } } catch (...) @@ -204,7 +208,7 @@ bool CViewDatabase::ClearViewStates(int windowID) if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL("delete from view where window = %i", windowID); - m_pDS->exec(sql.c_str()); + m_pDS->exec(sql); } catch (...) { diff --git a/xbmc/view/ViewStateSettings.cpp b/xbmc/view/ViewStateSettings.cpp index f547e866f7..cf3beb3419 100644 --- a/xbmc/view/ViewStateSettings.cpp +++ b/xbmc/view/ViewStateSettings.cpp @@ -18,9 +18,11 @@ * */ -#include <string.h> - #include "ViewStateSettings.h" + +#include <cstring> +#include <utility> + #include "threads/SingleLock.h" #include "utils/log.h" #include "utils/SortUtils.h" diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp index b5bdf0d511..dafc680979 100644 --- a/xbmc/windowing/X11/WinSystemX11.cpp +++ b/xbmc/windowing/X11/WinSystemX11.cpp @@ -399,10 +399,14 @@ void CWinSystemX11::UpdateResolutions() mode.id.c_str(), mode.name.c_str(), mode.hz, mode.w, mode.h); RESOLUTION_INFO res; res.iScreen = 0; // not used by X11 + res.dwFlags = 0; res.iWidth = mode.w; res.iHeight = mode.h; res.iScreenWidth = mode.w; res.iScreenHeight = mode.h; + if (mode.IsInterlaced()) + res.dwFlags |= D3DPRESENTFLAG_INTERLACED; + if (!m_bIsRotated) { res.iWidth = mode.w; @@ -427,11 +431,6 @@ void CWinSystemX11::UpdateResolutions() res.fRefreshRate = mode.hz; res.bFullScreen = true; - if (mode.h > 0 && ((float)mode.w / (float)mode.h >= 1.59)) - res.dwFlags = D3DPRESENTFLAG_WIDESCREEN; - else - res.dwFlags = 0; - g_graphicsContext.ResetOverscan(res); CDisplaySettings::GetInstance().AddResolutionInfo(res); } diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h index 4b1ff93c12..3d54108840 100644 --- a/xbmc/windowing/X11/XRandR.h +++ b/xbmc/windowing/X11/XRandR.h @@ -33,32 +33,36 @@ class XMode { public: XMode() - { - id=""; - name=""; - hz=0.0f; - isPreferred=false; - isCurrent=false; - w=h=0; - } + { + id=""; + name=""; + hz=0.0f; + isPreferred=false; + isCurrent=false; + w=h=0; + } bool operator==(XMode& mode) const - { - if (id!=mode.id) - return false; - if (name!=mode.name) - return false; - if (hz!=mode.hz) - return false; - if (isPreferred!=mode.isPreferred) - return false; - if (isCurrent!=mode.isCurrent) - return false; - if (w!=mode.w) - return false; - if (h!=mode.h) - return false; - return true; - } + { + if (id != mode.id) + return false; + if (name != mode.name) + return false; + if (hz != mode.hz) + return false; + if (isPreferred != mode.isPreferred) + return false; + if (isCurrent != mode.isCurrent) + return false; + if (w != mode.w) + return false; + if (h != mode.h) + return false; + return true; + } + bool IsInterlaced() + { + return name.back() == 'i'; + } std::string id; std::string name; float hz; @@ -72,11 +76,11 @@ class XOutput { public: XOutput() - { - name=""; - isConnected=false; - w=h=x=y=wmm=hmm=0; - } + { + name = ""; + isConnected = false; + w = h = x = y = wmm = hmm = 0; + } std::string name; bool isConnected; int screen; @@ -98,8 +102,8 @@ public: bool Query(bool force=false, bool ignoreoff=true); bool Query(bool force, int screennum, bool ignoreoff=true); std::vector<XOutput> GetModes(void); - XMode GetCurrentMode(const std::string& outputName); - XMode GetPreferredMode(const std::string& outputName); + XMode GetCurrentMode(const std::string& outputName); + XMode GetPreferredMode(const std::string& outputName); XOutput *GetOutput(const std::string& outputName); bool SetMode(XOutput output, XMode mode); void LoadCustomModeLinesToAllOutputs(void); diff --git a/xbmc/windows/GUIWindowScreensaver.cpp b/xbmc/windows/GUIWindowScreensaver.cpp index 1fedb2e26e..a18882bcbf 100644 --- a/xbmc/windows/GUIWindowScreensaver.cpp +++ b/xbmc/windows/GUIWindowScreensaver.cpp @@ -122,8 +122,6 @@ bool CGUIWindowScreensaver::OnMessage(CGUIMessage& message) // RESOLUTION res = g_graphicsContext.GetVideoResolution(); // g_graphicsContext.SetVideoResolution(res, FALSE); - // enable the overlay - g_windowManager.ShowOverlay(OVERLAY_STATE_SHOWN); } break; @@ -154,8 +152,6 @@ bool CGUIWindowScreensaver::OnMessage(CGUIMessage& message) // RESOLUTION res = g_graphicsContext.GetVideoResolution(); // g_graphicsContext.SetVideoResolution(res, TRUE); - // disable the overlay - g_windowManager.ShowOverlay(OVERLAY_STATE_HIDDEN); return true; } case GUI_MSG_CHECK_LOCK: diff --git a/xbmc/windows/GUIWindowWeather.cpp b/xbmc/windows/GUIWindowWeather.cpp index e7aeaa2d2b..2f53664a80 100644 --- a/xbmc/windows/GUIWindowWeather.cpp +++ b/xbmc/windows/GUIWindowWeather.cpp @@ -18,17 +18,17 @@ * */ -#include "system.h" -#include "GUIUserMessages.h" -#include "dialogs/GUIDialogOK.h" #include "GUIWindowWeather.h" -#include "utils/Weather.h" -#include "utils/URIUtils.h" -#include "utils/Variant.h" -#ifdef HAS_PYTHON -#endif + +#include <utility> + +#include "dialogs/GUIDialogOK.h" +#include "GUIUserMessages.h" #include "LangInfo.h" #include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include "utils/Variant.h" +#include "utils/Weather.h" using namespace ADDON; |