diff options
author | tamland <thomas.amland@gmail.com> | 2015-08-08 12:49:49 +0200 |
---|---|---|
committer | tamland <thomas.amland@gmail.com> | 2015-08-08 12:49:49 +0200 |
commit | e32987a697f1cfbecfe2043ede0db4e0bf234d29 (patch) | |
tree | 1a20fd4aca95d8d9574ee266b46ba3bf0c710d21 | |
parent | 5f938e2b7b093379a35d0f51f616b38227e68d35 (diff) | |
parent | b2dfa4ed125cdc8cd2ce602eadf99328ad99b302 (diff) |
Merge pull request #7544 from tamland/context_menu_groups
[addons] extend context menu system
-rw-r--r-- | Kodi.xcodeproj/project.pbxproj | 30 | ||||
-rw-r--r-- | addons/resource.language.en_gb/resources/strings.po | 2 | ||||
-rw-r--r-- | addons/xbmc.python/contextitem.xsd | 28 | ||||
-rw-r--r-- | project/VS2010Express/XBMC.vcxproj | 6 | ||||
-rw-r--r-- | project/VS2010Express/XBMC.vcxproj.filters | 6 | ||||
-rw-r--r-- | xbmc/ContextMenuItem.cpp | 106 | ||||
-rw-r--r-- | xbmc/ContextMenuItem.h | 63 | ||||
-rw-r--r-- | xbmc/ContextMenuManager.cpp | 120 | ||||
-rw-r--r-- | xbmc/ContextMenuManager.h | 41 | ||||
-rw-r--r-- | xbmc/Makefile.in | 1 | ||||
-rw-r--r-- | xbmc/addons/Addon.cpp | 10 | ||||
-rw-r--r-- | xbmc/addons/AddonManager.cpp | 6 | ||||
-rw-r--r-- | xbmc/addons/ContextItemAddon.cpp | 72 | ||||
-rw-r--r-- | xbmc/addons/ContextItemAddon.h | 66 | ||||
-rw-r--r-- | xbmc/addons/ContextMenuAddon.cpp | 129 | ||||
-rw-r--r-- | xbmc/addons/ContextMenuAddon.h | 47 | ||||
-rw-r--r-- | xbmc/addons/Makefile | 2 | ||||
-rw-r--r-- | xbmc/dialogs/GUIDialogFavourites.cpp | 2 | ||||
-rw-r--r-- | xbmc/video/dialogs/GUIDialogVideoInfo.cpp | 4 | ||||
-rw-r--r-- | xbmc/windows/GUIMediaWindow.cpp | 2 | ||||
-rw-r--r-- | xbmc/windows/GUIWindowLoginScreen.cpp | 2 |
21 files changed, 515 insertions, 230 deletions
diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 1ca94d7f27..ebfd42935b 100644 --- a/Kodi.xcodeproj/project.pbxproj +++ b/Kodi.xcodeproj/project.pbxproj @@ -214,9 +214,6 @@ 395C2A191A9F074C00EBC7AD /* Locale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A171A9F074C00EBC7AD /* Locale.cpp */; }; 395C2A1A1A9F074C00EBC7AD /* Locale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A171A9F074C00EBC7AD /* Locale.cpp */; }; 395C2A1B1A9F074C00EBC7AD /* Locale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A171A9F074C00EBC7AD /* Locale.cpp */; }; - 395C2A1F1A9F96A700EBC7AD /* ContextItemAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A1D1A9F96A700EBC7AD /* ContextItemAddon.cpp */; }; - 395C2A201A9F96A700EBC7AD /* ContextItemAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A1D1A9F96A700EBC7AD /* ContextItemAddon.cpp */; }; - 395C2A211A9F96A700EBC7AD /* ContextItemAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A1D1A9F96A700EBC7AD /* ContextItemAddon.cpp */; }; 395C2A241AA4C32100EBC7AD /* AudioDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A221AA4C32100EBC7AD /* AudioDecoder.cpp */; }; 395C2A251AA4C32100EBC7AD /* AudioDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A221AA4C32100EBC7AD /* AudioDecoder.cpp */; }; 395C2A261AA4C32100EBC7AD /* AudioDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 395C2A221AA4C32100EBC7AD /* AudioDecoder.cpp */; }; @@ -891,6 +888,12 @@ DF527736151BAF4C00B5B63B /* WebSocketV13.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52772F151BAF4C00B5B63B /* WebSocketV13.cpp */; }; DF527737151BAF4C00B5B63B /* WebSocketV8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527731151BAF4C00B5B63B /* WebSocketV8.cpp */; }; DF529BAE1741697B00523FB4 /* Environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF529BAC1741697B00523FB4 /* Environment.cpp */; }; + DF54F7FE1B6580AD000FCBA4 /* ContextMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF54F7FC1B6580AC000FCBA4 /* ContextMenuItem.cpp */; }; + DF54F7FF1B6580AD000FCBA4 /* ContextMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF54F7FC1B6580AC000FCBA4 /* ContextMenuItem.cpp */; }; + DF54F8001B6580AD000FCBA4 /* ContextMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF54F7FC1B6580AC000FCBA4 /* ContextMenuItem.cpp */; }; + DF54F8031B6580C8000FCBA4 /* ContextMenuAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF54F8011B6580C8000FCBA4 /* ContextMenuAddon.cpp */; }; + DF54F8041B6580C8000FCBA4 /* ContextMenuAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF54F8011B6580C8000FCBA4 /* ContextMenuAddon.cpp */; }; + DF54F8051B6580C8000FCBA4 /* ContextMenuAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF54F8011B6580C8000FCBA4 /* ContextMenuAddon.cpp */; }; DF56EF1F1A798A3F00CAAEFB /* HTTPFileHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF56EF1D1A798A3F00CAAEFB /* HTTPFileHandler.cpp */; }; DF56EF201A798A3F00CAAEFB /* HTTPFileHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF56EF1D1A798A3F00CAAEFB /* HTTPFileHandler.cpp */; }; DF56EF211A798A3F00CAAEFB /* HTTPFileHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF56EF1D1A798A3F00CAAEFB /* HTTPFileHandler.cpp */; }; @@ -3590,8 +3593,6 @@ 395C2A101A9F072400EBC7AD /* ResourceFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceFile.h; sourceTree = "<group>"; }; 395C2A171A9F074C00EBC7AD /* Locale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Locale.cpp; sourceTree = "<group>"; }; 395C2A181A9F074C00EBC7AD /* Locale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Locale.h; sourceTree = "<group>"; }; - 395C2A1D1A9F96A700EBC7AD /* ContextItemAddon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContextItemAddon.cpp; sourceTree = "<group>"; }; - 395C2A1E1A9F96A700EBC7AD /* ContextItemAddon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextItemAddon.h; sourceTree = "<group>"; }; 395C2A221AA4C32100EBC7AD /* AudioDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDecoder.cpp; sourceTree = "<group>"; }; 395C2A231AA4C32100EBC7AD /* AudioDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDecoder.h; sourceTree = "<group>"; }; 395F6DDB1A8133360088CC74 /* GUIDialogSimpleMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogSimpleMenu.cpp; sourceTree = "<group>"; }; @@ -4521,6 +4522,10 @@ DF527732151BAF4C00B5B63B /* WebSocketV8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketV8.h; sourceTree = "<group>"; }; DF529BAC1741697B00523FB4 /* Environment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Environment.cpp; sourceTree = "<group>"; }; DF529BAD1741697B00523FB4 /* Environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Environment.h; sourceTree = "<group>"; }; + DF54F7FC1B6580AC000FCBA4 /* ContextMenuItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContextMenuItem.cpp; sourceTree = "<group>"; }; + DF54F7FD1B6580AC000FCBA4 /* ContextMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuItem.h; sourceTree = "<group>"; }; + DF54F8011B6580C8000FCBA4 /* ContextMenuAddon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContextMenuAddon.cpp; sourceTree = "<group>"; }; + DF54F8021B6580C8000FCBA4 /* ContextMenuAddon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuAddon.h; sourceTree = "<group>"; }; DF56EF1D1A798A3F00CAAEFB /* HTTPFileHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPFileHandler.cpp; sourceTree = "<group>"; }; DF56EF1E1A798A3F00CAAEFB /* HTTPFileHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPFileHandler.h; sourceTree = "<group>"; }; DF56EF221A798A5E00CAAEFB /* HttpRangeUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpRangeUtils.cpp; sourceTree = "<group>"; }; @@ -5927,8 +5932,8 @@ 395C2A231AA4C32100EBC7AD /* AudioDecoder.h */, 7CF34D9D1930264A00D543C5 /* AudioEncoder.cpp */, 7CF34D9E1930264A00D543C5 /* AudioEncoder.h */, - 395C2A1D1A9F96A700EBC7AD /* ContextItemAddon.cpp */, - 395C2A1E1A9F96A700EBC7AD /* ContextItemAddon.h */, + DF54F8011B6580C8000FCBA4 /* ContextMenuAddon.cpp */, + DF54F8021B6580C8000FCBA4 /* ContextMenuAddon.h */, 18B49FF61152BFA5001AF8A6 /* DllAddon.h */, 18B7C38612942090009E7A26 /* GUIDialogAddonInfo.cpp */, 18B7C38712942090009E7A26 /* GUIDialogAddonInfo.h */, @@ -8272,6 +8277,8 @@ E38E14720D25F9F900618676 /* BackgroundInfoLoader.cpp */, E38E14730D25F9F900618676 /* BackgroundInfoLoader.h */, F5B413131065900C0035D105 /* config.h */, + DF54F7FC1B6580AC000FCBA4 /* ContextMenuItem.cpp */, + DF54F7FD1B6580AC000FCBA4 /* ContextMenuItem.h */, 395C29F91A9CD20C00EBC7AD /* ContextMenuManager.cpp */, 395C29FA1A9CD20C00EBC7AD /* ContextMenuManager.h */, E38E167E0D25F9FA00618676 /* CueDocument.cpp */, @@ -10288,6 +10295,7 @@ E38E20510D25F9FD00618676 /* PluginDirectory.cpp in Sources */, E38E20520D25F9FD00618676 /* RarDirectory.cpp in Sources */, E38E20530D25F9FD00618676 /* RarManager.cpp in Sources */, + DF54F7FE1B6580AD000FCBA4 /* ContextMenuItem.cpp in Sources */, 395C29C51A98A0E100EBC7AD /* ILanguageInvoker.cpp in Sources */, E38E20580D25F9FD00618676 /* SmartPlaylistDirectory.cpp in Sources */, E38E205B0D25F9FD00618676 /* StackDirectory.cpp in Sources */, @@ -10875,6 +10883,7 @@ C84828C8156CFCD8005A996F /* GUIDialogPVRChannelManager.cpp in Sources */, C84828C9156CFCD8005A996F /* GUIDialogPVRChannelsOSD.cpp in Sources */, C84828CC156CFCD8005A996F /* GUIDialogPVRGroupManager.cpp in Sources */, + DF54F8031B6580C8000FCBA4 /* ContextMenuAddon.cpp in Sources */, C84828CD156CFCD8005A996F /* GUIDialogPVRGuideInfo.cpp in Sources */, C84828CE156CFCD8005A996F /* GUIDialogPVRGuideOSD.cpp in Sources */, C84828CF156CFCD8005A996F /* GUIDialogPVRGuideSearch.cpp in Sources */, @@ -11078,7 +11087,6 @@ 7C1409A9184015C9009F9411 /* InfoExpression.cpp in Sources */, AE32174218313ADF0003FAFC /* XSLTUtils.cpp in Sources */, 7C15DCBC1892481400FCE564 /* InfoBool.cpp in Sources */, - 395C2A1F1A9F96A700EBC7AD /* ContextItemAddon.cpp in Sources */, F5CC228B1814F7E9006B5E91 /* AESinkDARWINOSX.cpp in Sources */, F5CC22EB1814FF3B006B5E91 /* ActiveAE.cpp in Sources */, F5CC22EC1814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */, @@ -11583,6 +11591,7 @@ DFF0F28217528350002DA3A4 /* GUIControlFactory.cpp in Sources */, DFF0F28317528350002DA3A4 /* GUIControlGroup.cpp in Sources */, DFF0F28417528350002DA3A4 /* GUIControlGroupList.cpp in Sources */, + DF54F8001B6580AD000FCBA4 /* ContextMenuItem.cpp in Sources */, DFF0F28517528350002DA3A4 /* GUIControlProfiler.cpp in Sources */, DFF0F28617528350002DA3A4 /* GUIDialog.cpp in Sources */, DFF0F28717528350002DA3A4 /* GUIEditControl.cpp in Sources */, @@ -11749,7 +11758,6 @@ DFF0F32417528350002DA3A4 /* HTTPVfsHandler.cpp in Sources */, DFF0F32517528350002DA3A4 /* HTTPWebinterfaceAddonsHandler.cpp in Sources */, DFF0F32617528350002DA3A4 /* HTTPWebinterfaceHandler.cpp in Sources */, - 395C2A211A9F96A700EBC7AD /* ContextItemAddon.cpp in Sources */, DFF0F32717528350002DA3A4 /* IHTTPRequestHandler.cpp in Sources */, DFF0F32817528350002DA3A4 /* NetworkLinux.cpp in Sources */, DFF0F32917528350002DA3A4 /* ZeroconfBrowserOSX.cpp in Sources */, @@ -11816,6 +11824,7 @@ DFF0F36117528350002DA3A4 /* PlayListM3U.cpp in Sources */, DF4BF0191A4EF31F0053AC56 /* cc_decoder.c in Sources */, DFF0F36217528350002DA3A4 /* PlayListPLS.cpp in Sources */, + DF54F8051B6580C8000FCBA4 /* ContextMenuAddon.cpp in Sources */, DFF0F36317528350002DA3A4 /* PlayListURL.cpp in Sources */, DFF0F36417528350002DA3A4 /* PlayListWPL.cpp in Sources */, DFEA4B5B1B52721300562321 /* GUIDialogAudioDSPManager.cpp in Sources */, @@ -12605,7 +12614,6 @@ E49912C9174E5DA000741B6D /* DirectoryNodeRecentlyAddedMusicVideos.cpp in Sources */, E49912CA174E5DA000741B6D /* DirectoryNodeRoot.cpp in Sources */, E49912CB174E5DA000741B6D /* DirectoryNodeSeasons.cpp in Sources */, - 395C2A201A9F96A700EBC7AD /* ContextItemAddon.cpp in Sources */, E49912CC174E5DA000741B6D /* DirectoryNodeTitleMovies.cpp in Sources */, E49912CD174E5DA000741B6D /* DirectoryNodeTitleMusicVideos.cpp in Sources */, DFDE5D521AE5658200EE53AD /* PictureScalingAlgorithm.cpp in Sources */, @@ -12771,6 +12779,7 @@ E499137C174E5F0E00741B6D /* GUIDialogKaraokeSongSelector.cpp in Sources */, E499137D174E5F0E00741B6D /* GUIWindowKaraokeLyrics.cpp in Sources */, E499137E174E5F0E00741B6D /* karaokelyrics.cpp in Sources */, + DF54F8041B6580C8000FCBA4 /* ContextMenuAddon.cpp in Sources */, E499137F174E5F0E00741B6D /* karaokelyricscdg.cpp in Sources */, E4991380174E5F0E00741B6D /* karaokelyricsfactory.cpp in Sources */, E4991381174E5F0E00741B6D /* karaokelyricsmanager.cpp in Sources */, @@ -13223,6 +13232,7 @@ 7CCDA187192753E30074CF51 /* PltTaskManager.cpp in Sources */, 7CCDA190192753E30074CF51 /* PltThreadTask.cpp in Sources */, 7CCDA199192753E30074CF51 /* PltUPnP.cpp in Sources */, + DF54F7FF1B6580AD000FCBA4 /* ContextMenuItem.cpp in Sources */, 7CCDA1A2192753E30074CF51 /* PltMediaConnect.cpp in Sources */, 7CCDA1AB192753E30074CF51 /* PltXbox360.cpp in Sources */, 7CCDA1B0192753E30074CF51 /* X_MS_MediaReceiverRegistrarSCPD.cpp in Sources */, diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 10c39b9fe5..3fa1dbc367 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -13110,7 +13110,7 @@ msgstr "" #. Used as the type name for context item addons #: xbmc/addons/Addons.cpp msgctxt "#24025" -msgid "Context items" +msgid "Context menus" msgstr "" #: xbmc/addons/Addon.cpp diff --git a/addons/xbmc.python/contextitem.xsd b/addons/xbmc.python/contextitem.xsd index 3c7c671528..0baa6f999a 100644 --- a/addons/xbmc.python/contextitem.xsd +++ b/addons/xbmc.python/contextitem.xsd @@ -4,26 +4,30 @@ <xs:element name="extension"> <xs:complexType> <xs:sequence> - <xs:element name="item"> - <xs:complexType> - <xs:sequence> - <xs:element name="label" type="xs:string"/> - <xs:element name="visible" type="xs:string"/> - <xs:element name="parent" type="xs:string"/> - </xs:sequence> - </xs:complexType> - </xs:element> + <xs:element name="menu" type="menuType" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="point" type="xs:string" use="required"/> <xs:attribute name="id" type="simpleIdentifier"/> - <xs:attribute name="name" type="xs:string"/> - <xs:attribute name="library" type="xs:string" use="required"/> </xs:complexType> </xs:element> + <xs:complexType name="itemType"> + <xs:sequence> + <xs:element name="label" type="xs:string"/> + <xs:element name="visible" type="xs:string"/> + </xs:sequence> + <xs:attribute name="library" type="xs:string" use="required"/> + </xs:complexType> + <xs:complexType name="menuType"> + <xs:sequence> + <xs:element name="label" type="xs:string" minOccurs="0"/> + <xs:element name="item" type="itemType" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="menu" type="menuType" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="id" type="xs:string"/> + </xs:complexType> <xs:simpleType name="simpleIdentifier"> <xs:restriction base="xs:string"> <xs:pattern value="[^.]+"/> </xs:restriction> </xs:simpleType> </xs:schema> - diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index bf000da93a..93a1ec7162 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -190,7 +190,7 @@ <ClCompile Include="..\..\xbmc\addons\AddonDatabase.cpp" /> <ClCompile Include="..\..\xbmc\addons\AddonInstaller.cpp" /> <ClCompile Include="..\..\xbmc\addons\AddonVersion.cpp" /> - <ClCompile Include="..\..\xbmc\addons\ContextItemAddon.cpp" /> + <ClCompile Include="..\..\xbmc\addons\ContextMenuAddon.cpp" /> <ClCompile Include="..\..\xbmc\addons\AudioDecoder.cpp" /> <ClCompile Include="..\..\xbmc\addons\GUIDialogAddonInfo.cpp" /> <ClCompile Include="..\..\xbmc\addons\GUIDialogAddonSettings.cpp" /> @@ -211,6 +211,7 @@ <ClCompile Include="..\..\xbmc\AutoSwitch.cpp" /> <ClCompile Include="..\..\xbmc\BackgroundInfoLoader.cpp" /> <ClCompile Include="..\..\xbmc\CompileInfo.cpp" /> + <ClCompile Include="..\..\xbmc\ContextMenuItem.cpp" /> <ClCompile Include="..\..\xbmc\ContextMenuManager.cpp" /> <ClCompile Include="..\..\xbmc\contrib\kissfft\kiss_fft.c"> <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs> @@ -857,7 +858,7 @@ <ClInclude Include="..\..\xbmc\addons\AddonCallbacksAudioDSP.h" /> <ClInclude Include="..\..\xbmc\addons\AddonCallbacksCodec.h" /> <ClInclude Include="..\..\xbmc\addons\AudioDecoder.h" /> - <ClInclude Include="..\..\xbmc\addons\ContextItemAddon.h" /> + <ClInclude Include="..\..\xbmc\addons\ContextMenuAddon.h" /> <ClInclude Include="..\..\xbmc\addons\ImageResource.h" /> <ClInclude Include="..\..\xbmc\addons\Webinterface.h" /> <ClInclude Include="..\..\xbmc\addons\UISoundsResource.h" /> @@ -1726,6 +1727,7 @@ <ClInclude Include="..\..\xbmc\Autorun.h" /> <ClInclude Include="..\..\xbmc\AutoSwitch.h" /> <ClInclude Include="..\..\xbmc\BackgroundInfoLoader.h" /> + <ClInclude Include="..\..\xbmc\ContextMenuItem.h" /> <ClInclude Include="..\..\xbmc\ContextMenuManager.h" /> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDDemuxers\DVDDemuxPVRClient.h" /> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDInputStreams\DVDInputStreamBluray.h" /> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index 44a8402a2b..e37e781f64 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -744,7 +744,7 @@ <ClCompile Include="..\..\xbmc\addons\AudioEncoder.cpp"> <Filter>addons</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\addons\ContextItemAddon.cpp"> + <ClCompile Include="..\..\xbmc\addons\ContextMenuAddon.cpp"> <Filter>addons</Filter> </ClCompile> <ClCompile Include="..\..\xbmc\addons\Scraper.cpp"> @@ -2227,6 +2227,7 @@ <ClCompile Include="..\..\xbmc\AutoSwitch.cpp" /> <ClCompile Include="..\..\xbmc\DynamicDll.cpp" /> <ClCompile Include="..\..\xbmc\CueDocument.cpp" /> + <ClCompile Include="..\..\xbmc\ContextMenuItem.cpp" /> <ClCompile Include="..\..\xbmc\ContextMenuManager.cpp" /> <ClCompile Include="..\..\xbmc\FileItem.cpp" /> <ClCompile Include="..\..\xbmc\GUIInfoManager.cpp" /> @@ -3622,7 +3623,7 @@ <ClInclude Include="..\..\xbmc\addons\AudioEncoder.h"> <Filter>addons</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\addons\ContextItemAddon.h"> + <ClInclude Include="..\..\xbmc\addons\ContextMenuAddon.h"> <Filter>addons</Filter> </ClInclude> <ClInclude Include="..\..\xbmc\addons\DllAddon.h"> @@ -5243,6 +5244,7 @@ <ClInclude Include="..\..\xbmc\AutoSwitch.h" /> <ClInclude Include="..\..\xbmc\DynamicDll.h" /> <ClInclude Include="..\..\xbmc\CueDocument.h" /> + <ClInclude Include="..\..\xbmc\ContextMenuItem.h" /> <ClInclude Include="..\..\xbmc\ContextMenuManager.h" /> <ClInclude Include="..\..\xbmc\FileItem.h" /> <ClInclude Include="..\..\xbmc\GUIInfoManager.h" /> diff --git a/xbmc/ContextMenuItem.cpp b/xbmc/ContextMenuItem.cpp new file mode 100644 index 0000000000..c9a382e863 --- /dev/null +++ b/xbmc/ContextMenuItem.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 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/>. + * + */ + +#include "ContextMenuItem.h" +#include "addons/Addon.h" +#include "addons/AddonManager.h" +#include "addons/ContextMenuAddon.h" +#include "addons/IAddon.h" +#include "interfaces/generic/ScriptInvocationManager.h" +#include "interfaces/python/ContextItemAddonInvoker.h" +#include "interfaces/python/XBPython.h" +#include "utils/StringUtils.h" +#include <boost/lexical_cast.hpp> + + +std::string CContextMenuItem::GetLabel() const +{ + if (!m_addon) + return ""; + + if (StringUtils::IsNaturalNumber(m_label)) + return m_addon->GetString(boost::lexical_cast<int>(m_label.c_str())); + + return m_label; +} + +bool CContextMenuItem::IsVisible(const CFileItemPtr& item) const +{ + return IsGroup() || (item && m_condition && m_condition->Get(item.get())); +} + +bool CContextMenuItem::IsParentOf(const CContextMenuItem& other) const +{ + return !m_groupId.empty() && (m_groupId == other.m_parent); +} + +bool CContextMenuItem::IsGroup() const +{ + return !m_groupId.empty(); +} + +bool CContextMenuItem::Execute(const CFileItemPtr& item) const +{ + if (!item || !m_addon || m_library.empty() || IsGroup()) + return false; + + LanguageInvokerPtr invoker(new CContextItemAddonInvoker(&g_pythonParser, item)); + return (CScriptInvocationManager::Get().ExecuteAsync(m_library, invoker, m_addon) != -1); +} + +bool CContextMenuItem::operator==(const CContextMenuItem& other) const +{ + if (IsGroup() && other.IsGroup()) + return (m_groupId == other.m_groupId && m_parent == other.m_parent); + + return (IsGroup() == other.IsGroup()) + && (m_parent == other.m_parent) + && (m_library == other.m_library) + && ((!m_addon && !other.m_addon) || (m_addon && other.m_addon && m_addon->ID() == other.m_addon->ID())); +} + +std::string CContextMenuItem::ToString() const +{ + if (IsGroup()) + return StringUtils::Format("CContextMenuItem[group, id=%s, parent=%s, addon=%s]", + m_groupId.c_str(), m_parent.c_str(), m_addon ? m_addon->ID().c_str() : "null"); + else + return StringUtils::Format("CContextMenuItem[item, parent=%s, library=%s, addon=%s]", + m_parent.c_str(), m_library.c_str(), m_addon ? m_addon->ID().c_str() : "null"); +} + +CContextMenuItem CContextMenuItem::CreateGroup(const std::string& label, const std::string& parent, const std::string& groupId) +{ + CContextMenuItem menuItem; + menuItem.m_label = label; + menuItem.m_parent = parent; + menuItem.m_groupId = groupId; + return menuItem; +} + +CContextMenuItem CContextMenuItem::CreateItem(const std::string& label, const std::string& parent, const std::string& library, const INFO::InfoPtr& condition) +{ + CContextMenuItem menuItem; + menuItem.m_label = label; + menuItem.m_parent = parent; + menuItem.m_library = library; + menuItem.m_condition = condition; + return menuItem; +} diff --git a/xbmc/ContextMenuItem.h b/xbmc/ContextMenuItem.h new file mode 100644 index 0000000000..b1e57bc6d0 --- /dev/null +++ b/xbmc/ContextMenuItem.h @@ -0,0 +1,63 @@ +#pragma once +/* + * Copyright (C) 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/>. + * + */ + +#include <map> +#include "addons/ContextMenuAddon.h" +#include "addons/IAddon.h" +#include "dialogs/GUIDialogContextMenu.h" + +namespace ADDON +{ + class CContextMenuAddon; +} + +class CContextMenuItem +{ +public: + std::string GetLabel() const; + bool IsVisible(const CFileItemPtr& item) const; + bool IsParentOf(const CContextMenuItem& menuItem) const; + bool IsGroup() const; + bool Execute(const CFileItemPtr& item) const; + bool operator==(const CContextMenuItem& other) const; + std::string ToString() const; + + static CContextMenuItem CreateGroup( + const std::string& label, + const std::string& parent, + const std::string& groupId); + + static CContextMenuItem CreateItem( + const std::string& label, + const std::string& parent, + const std::string& library, + const INFO::InfoPtr& condition); + + friend class ADDON::CContextMenuAddon; + +private: + std::string m_label; + std::string m_parent; + std::string m_groupId; + std::string m_library; + INFO::InfoPtr m_condition; + ADDON::AddonPtr m_addon; +}; diff --git a/xbmc/ContextMenuManager.cpp b/xbmc/ContextMenuManager.cpp index 4f9f88dc2f..b4d05d8473 100644 --- a/xbmc/ContextMenuManager.cpp +++ b/xbmc/ContextMenuManager.cpp @@ -19,21 +19,26 @@ */ #include "ContextMenuManager.h" +#include "ContextMenuItem.h" #include "addons/Addon.h" #include "addons/AddonManager.h" -#include "addons/ContextItemAddon.h" +#include "addons/ContextMenuAddon.h" #include "addons/IAddon.h" #include "interfaces/generic/ScriptInvocationManager.h" #include "interfaces/python/ContextItemAddonInvoker.h" #include "interfaces/python/XBPython.h" +#include "utils/log.h" using namespace ADDON; -typedef std::map<unsigned int, ContextItemAddonPtr>::value_type ValueType; +typedef std::pair<unsigned int, CContextMenuItem> Item; + +const CContextMenuItem CContextMenuManager::MAIN = CContextMenuItem::CreateGroup("", "", "kodi.core.main"); +const CContextMenuItem CContextMenuManager::MANAGE = CContextMenuItem::CreateGroup("", "", "kodi.core.manage"); CContextMenuManager::CContextMenuManager() - : m_iCurrentContextId(CONTEXT_BUTTON_FIRST_ADDON) + : m_nextButtonId(CONTEXT_BUTTON_FIRST_ADDON) { Init(); } @@ -46,20 +51,32 @@ CContextMenuManager& CContextMenuManager::Get() void CContextMenuManager::Init() { - //Make sure we load all context items on first usage... VECADDONS addons; if (CAddonMgr::Get().GetAddons(ADDON_CONTEXT_ITEM, addons)) - { for (const auto& addon : addons) - Register(std::static_pointer_cast<CContextItemAddon>(addon)); - } + Register(std::static_pointer_cast<CContextMenuAddon>(addon)); } void CContextMenuManager::Register(const ContextItemAddonPtr& cm) { if (!cm) return; - m_contextAddons[m_iCurrentContextId++] = cm; + + for (const auto& menuItem : cm->GetItems()) + { + auto existing = std::find_if(m_items.begin(), m_items.end(), + [&](const Item& kv){ return kv.second == menuItem; }); + if (existing != m_items.end()) + { + if (!menuItem.GetLabel().empty()) + existing->second = menuItem; + } + else + { + m_items.push_back(std::make_pair(m_nextButtonId, menuItem)); + ++m_nextButtonId; + } + } } bool CContextMenuManager::Unregister(const ContextItemAddonPtr& cm) @@ -67,47 +84,88 @@ bool CContextMenuManager::Unregister(const ContextItemAddonPtr& cm) if (!cm) return false; - auto it = std::find_if(m_contextAddons.begin(), m_contextAddons.end(), - [&](const ValueType& value){ return value.second->ID() == cm->ID(); }); - - if (it != m_contextAddons.end()) - { - m_contextAddons.erase(it); - return true; - } - return false; + const auto menuItems = cm->GetItems(); + + auto it = std::remove_if(m_items.begin(), m_items.end(), + [&](const Item& kv) + { + if (kv.second.IsGroup()) + return false; //keep in case other items use them + return std::find(menuItems.begin(), menuItems.end(), kv.second) != menuItems.end(); + } + ); + m_items.erase(it, m_items.end()); + return true; } -ContextItemAddonPtr CContextMenuManager::GetContextItemByID(unsigned int id) +bool CContextMenuManager::IsVisible( + const CContextMenuItem& menuItem, const CContextMenuItem& root, const CFileItemPtr& fileItem) { - auto it = m_contextAddons.find(id); - if (it != m_contextAddons.end()) - return it->second; - return ContextItemAddonPtr(); + if (menuItem.GetLabel().empty() || !root.IsParentOf(menuItem)) + return false; + + if (menuItem.IsGroup()) + return std::any_of(m_items.begin(), m_items.end(), + [&](const Item& kv){ return menuItem.IsParentOf(kv.second) && kv.second.IsVisible(fileItem); }); + + return menuItem.IsVisible(fileItem); } -void CContextMenuManager::AddVisibleItems(const CFileItemPtr& item, CContextButtons& list, const std::string& parent /* = "" */) +void CContextMenuManager::AddVisibleItems( + const CFileItemPtr& item, CContextButtons& list, const CContextMenuItem& root /* = CContextMenuItem::MAIN */) { if (!item) return; - for (const auto& kv : m_contextAddons) + const int initialSize = list.size(); + + for (const auto& kv : m_items) + if (IsVisible(kv.second, root, item)) + list.push_back(std::make_pair(kv.first, kv.second.GetLabel())); + + if (root == MAIN || root == MANAGE) { - if (kv.second->GetParent() == parent && kv.second->IsVisible(item)) - list.push_back(std::make_pair(kv.first, kv.second->GetLabel())); + std::stable_sort(list.begin() + initialSize, list.end(), + [](const std::pair<int, std::string>& lhs, const std::pair<int, std::string>& rhs) + { + return lhs.second < rhs.second; + } + ); } } -bool CContextMenuManager::Execute(unsigned int id, const CFileItemPtr& item) + +bool CContextMenuManager::OnClick(unsigned int id, const CFileItemPtr& item) { if (!item) return false; - const ContextItemAddonPtr addon = GetContextItemByID(id); - if (!addon || !addon->IsVisible(item)) + auto it = std::find_if(m_items.begin(), m_items.end(), + [id](const Item& kv){ return kv.first == id; }); + if (it == m_items.end()) + { + CLog::Log(LOGERROR, "CContextMenuManager: unknown button id '%u'", id); return false; + } + + CContextMenuItem menuItem = it->second; + if (menuItem.IsGroup()) + { + CLog::Log(LOGDEBUG, "CContextMenuManager: showing group '%s'", menuItem.ToString().c_str()); + CContextButtons choices; + AddVisibleItems(item, choices, menuItem); + if (choices.empty()) + { + CLog::Log(LOGERROR, "CContextMenuManager: no items in group '%s'", menuItem.ToString().c_str()); + return false; + } + int choice = CGUIDialogContextMenu::ShowAndGetChoice(choices); + if (choice == -1) + return false; + + return OnClick(choice, item); + } - LanguageInvokerPtr invoker(new CContextItemAddonInvoker(&g_pythonParser, item)); - return (CScriptInvocationManager::Get().ExecuteAsync(addon->LibPath(), invoker, addon) != -1); + return menuItem.Execute(item); } diff --git a/xbmc/ContextMenuManager.h b/xbmc/ContextMenuManager.h index 2dff9dce87..84d135036b 100644 --- a/xbmc/ContextMenuManager.h +++ b/xbmc/ContextMenuManager.h @@ -19,33 +19,37 @@ * */ -#include <map> -#include "addons/ContextItemAddon.h" +#include <vector> +#include "ContextMenuItem.h" +#include "addons/ContextMenuAddon.h" #include "dialogs/GUIDialogContextMenu.h" -#define CONTEXT_MENU_GROUP_MANAGE "kodi.core.manage" class CContextMenuManager { public: + static const CContextMenuItem MAIN; + static const CContextMenuItem MANAGE; + static CContextMenuManager& Get(); /*! - * \brief Executes a context menu item. - * \param id - id of the context button to execute. - * \param item - the currently selected item. - * \return true if executed successfully, false otherwise + * \param id - id of the context button clicked on. + * \param item - the selected file item. + * \return true on success, otherwise false. */ - bool Execute(unsigned int id, const CFileItemPtr& item); + bool OnClick(unsigned int id, const CFileItemPtr& item); /*! * \brief Adds all registered context item to the list. * \param item - the currently selected item. * \param list - the context menu. - * \param parent - the ID of the context menu. Empty string if the root menu. - * CONTEXT_MENU_GROUP_MANAGE if the 'manage' submenu. + * \param root - the context menu responsible for this call. */ - void AddVisibleItems(const CFileItemPtr& item, CContextButtons& list, const std::string& parent = ""); + void AddVisibleItems( + const CFileItemPtr& item, + CContextButtons& list, + const CContextMenuItem& root = MAIN); /*! * \brief Adds a context item to this manager. @@ -65,14 +69,11 @@ private: virtual ~CContextMenuManager() {} void Init(); + bool IsVisible( + const CContextMenuItem& menuItem, + const CContextMenuItem& root, + const CFileItemPtr& fileItem); - /*! - * \brief Get a context menu item by its assigned id. - * \param id - the button id of the context item. - * \return the addon or NULL if no item with given id is registered. - */ - ADDON::ContextItemAddonPtr GetContextItemByID(const unsigned int id); - - std::map<unsigned int, ADDON::ContextItemAddonPtr> m_contextAddons; - unsigned int m_iCurrentContextId; + std::vector<std::pair<unsigned int, CContextMenuItem>> m_items; + unsigned int m_nextButtonId; }; diff --git a/xbmc/Makefile.in b/xbmc/Makefile.in index 265920d361..e73a1d467d 100644 --- a/xbmc/Makefile.in +++ b/xbmc/Makefile.in @@ -4,6 +4,7 @@ SRCS=Application.cpp \ Autorun.cpp \ AutoSwitch.cpp \ BackgroundInfoLoader.cpp \ + ContextMenuItem.cpp \ ContextMenuManager.cpp \ CompileInfo.cpp \ CueDocument.cpp \ diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp index 69859abc65..a3b66cd1a5 100644 --- a/xbmc/addons/Addon.cpp +++ b/xbmc/addons/Addon.cpp @@ -646,7 +646,7 @@ void OnEnabled(const std::string& id) std::static_pointer_cast<CService>(addon)->Start(); if (CAddonMgr::Get().GetAddon(id, addon, ADDON_CONTEXT_ITEM)) - CContextMenuManager::Get().Register(std::static_pointer_cast<CContextItemAddon>(addon)); + CContextMenuManager::Get().Register(std::static_pointer_cast<CContextMenuAddon>(addon)); } void OnDisabled(const std::string& id) @@ -660,7 +660,7 @@ void OnDisabled(const std::string& id) std::static_pointer_cast<CService>(addon)->Stop(); if (CAddonMgr::Get().GetAddon(id, addon, ADDON_CONTEXT_ITEM, false)) - CContextMenuManager::Get().Unregister(std::static_pointer_cast<CContextItemAddon>(addon)); + CContextMenuManager::Get().Unregister(std::static_pointer_cast<CContextMenuAddon>(addon)); } void OnPreInstall(const AddonPtr& addon) @@ -672,7 +672,7 @@ void OnPreInstall(const AddonPtr& addon) std::static_pointer_cast<CService>(localAddon)->Stop(); if (CAddonMgr::Get().GetAddon(addon->ID(), localAddon, ADDON_CONTEXT_ITEM)) - CContextMenuManager::Get().Unregister(std::static_pointer_cast<CContextItemAddon>(localAddon)); + CContextMenuManager::Get().Unregister(std::static_pointer_cast<CContextMenuAddon>(localAddon)); //Fallback to the pre-install callback in the addon. //BUG: If primary extension point have changed we're calling the wrong method. @@ -686,7 +686,7 @@ void OnPostInstall(const AddonPtr& addon, bool update, bool modal) std::static_pointer_cast<CService>(localAddon)->Start(); if (CAddonMgr::Get().GetAddon(addon->ID(), localAddon, ADDON_CONTEXT_ITEM)) - CContextMenuManager::Get().Register(std::static_pointer_cast<CContextItemAddon>(localAddon)); + CContextMenuManager::Get().Register(std::static_pointer_cast<CContextMenuAddon>(localAddon)); addon->OnPostInstall(update, modal); } @@ -698,7 +698,7 @@ void OnPreUnInstall(const AddonPtr& addon) std::static_pointer_cast<CService>(localAddon)->Stop(); if (CAddonMgr::Get().GetAddon(addon->ID(), localAddon, ADDON_CONTEXT_ITEM)) - CContextMenuManager::Get().Unregister(std::static_pointer_cast<CContextItemAddon>(localAddon)); + CContextMenuManager::Get().Unregister(std::static_pointer_cast<CContextMenuAddon>(localAddon)); addon->OnPreUnInstall(); } diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp index 4abeb2c812..9b4aede1f1 100644 --- a/xbmc/addons/AddonManager.cpp +++ b/xbmc/addons/AddonManager.cpp @@ -53,7 +53,7 @@ #include "Repository.h" #include "Skin.h" #include "Service.h" -#include "ContextItemAddon.h" +#include "ContextMenuAddon.h" #include "Util.h" #include "addons/Webinterface.h" @@ -193,7 +193,7 @@ AddonPtr CAddonMgr::Factory(const cp_extension_t *props) case ADDON_REPOSITORY: return AddonPtr(new CRepository(props)); case ADDON_CONTEXT_ITEM: - return AddonPtr(new CContextItemAddon(props)); + return AddonPtr(new CContextMenuAddon(props)); default: break; } @@ -871,7 +871,7 @@ AddonPtr CAddonMgr::AddonFromProps(AddonProps& addonProps) case ADDON_REPOSITORY: return AddonPtr(new CRepository(addonProps)); case ADDON_CONTEXT_ITEM: - return AddonPtr(new CContextItemAddon(addonProps)); + return AddonPtr(new CContextMenuAddon(addonProps)); default: break; } diff --git a/xbmc/addons/ContextItemAddon.cpp b/xbmc/addons/ContextItemAddon.cpp deleted file mode 100644 index c3b1289846..0000000000 --- a/xbmc/addons/ContextItemAddon.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2013-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/>. - * - */ - -#include "ContextItemAddon.h" -#include "AddonManager.h" -#include "ContextMenuManager.h" -#include "GUIInfoManager.h" -#include "interfaces/info/InfoBool.h" -#include "utils/StringUtils.h" -#include <boost/lexical_cast.hpp> - -using namespace std; - -namespace ADDON -{ - -CContextItemAddon::CContextItemAddon(const AddonProps &props) - : CAddon(props) -{ } - -CContextItemAddon::~CContextItemAddon() -{ } - -CContextItemAddon::CContextItemAddon(const cp_extension_t *ext) - : CAddon(ext) -{ - ELEMENTS items; - if (CAddonMgr::Get().GetExtElements(ext->configuration, "item", items)) - { - cp_cfg_element_t *item = items[0]; - - m_label = CAddonMgr::Get().GetExtValue(item, "label"); - m_parent = CAddonMgr::Get().GetExtValue(item, "parent"); - - string visible = CAddonMgr::Get().GetExtValue(item, "visible"); - if (visible.empty()) - visible = "false"; - - m_visCondition = g_infoManager.Register(visible, 0); - } -} - -std::string CContextItemAddon::GetLabel() -{ - if (StringUtils::IsNaturalNumber(m_label)) - return GetString(boost::lexical_cast<int>(m_label.c_str())); - return m_label; -} - -bool CContextItemAddon::IsVisible(const CFileItemPtr& item) const -{ - return item && m_visCondition && m_visCondition->Get(item.get()); -} - -} diff --git a/xbmc/addons/ContextItemAddon.h b/xbmc/addons/ContextItemAddon.h deleted file mode 100644 index 49fa909a5b..0000000000 --- a/xbmc/addons/ContextItemAddon.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once -/* - * Copyright (C) 2013-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/>. - * - */ - -#include <list> -#include <memory> -#include "Addon.h" - -class CFileItem; -typedef std::shared_ptr<CFileItem> CFileItemPtr; - -namespace INFO -{ - class InfoBool; - typedef std::shared_ptr<InfoBool> InfoPtr; -} - -namespace ADDON -{ - class CContextItemAddon : public CAddon - { - public: - CContextItemAddon(const cp_extension_t *ext); - CContextItemAddon(const AddonProps &props); - virtual ~CContextItemAddon(); - - std::string GetLabel(); - - /*! - * \brief Get the parent category of this context item. - * - * \details Returns empty string if at root level or - * CONTEXT_MENU_GROUP_MANAGE when it should be in the 'manage' submenu. - */ - const std::string& GetParent() const { return m_parent; } - - /*! - * \brief Returns true if this contex menu should be visible for given item. - */ - bool IsVisible(const CFileItemPtr& item) const; - - private: - std::string m_label; - std::string m_parent; - INFO::InfoPtr m_visCondition; - }; - - typedef std::shared_ptr<CContextItemAddon> ContextItemAddonPtr; -} diff --git a/xbmc/addons/ContextMenuAddon.cpp b/xbmc/addons/ContextMenuAddon.cpp new file mode 100644 index 0000000000..f9fedd09b7 --- /dev/null +++ b/xbmc/addons/ContextMenuAddon.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2013-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/>. + * + */ + +#include "ContextMenuAddon.h" +#include "AddonManager.h" +#include "ContextMenuManager.h" +#include "ContextMenuItem.h" +#include "GUIInfoManager.h" +#include "interfaces/info/InfoBool.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include <sstream> + + +namespace ADDON +{ + +CContextMenuAddon::CContextMenuAddon(const AddonProps &props) + : CAddon(props) +{ } + +CContextMenuAddon::~CContextMenuAddon() +{ } + +CContextMenuAddon::CContextMenuAddon(const cp_extension_t *ext) + : CAddon(ext) +{ + cp_cfg_element_t* menu = CAddonMgr::Get().GetExtElement(ext->configuration, "menu"); + if (menu) + { + int tmp = 0; + ParseMenu(menu, "", tmp); + } + else + { + //backwards compatibility. add first item definition + ELEMENTS items; + if (CAddonMgr::Get().GetExtElements(ext->configuration, "item", items)) + { + cp_cfg_element_t *item = items[0]; + + std::string visCondition = CAddonMgr::Get().GetExtValue(item, "visible"); + if (visCondition.empty()) + visCondition = "false"; + + std::string parent = CAddonMgr::Get().GetExtValue(item, "parent") == "kodi.core.manage" + ? CContextMenuManager::MANAGE.m_groupId : CContextMenuManager::MAIN.m_groupId; + + CContextMenuItem menuItem = CContextMenuItem::CreateItem( + CAddonMgr::Get().GetExtValue(item, "label"), + parent, + LibPath(), + g_infoManager.Register(visCondition, 0)); + + m_items.push_back(menuItem); + } + } +} + +void CContextMenuAddon::ParseMenu(cp_cfg_element_t* elem, const std::string& parent, int& anonGroupCount) +{ + auto menuLabel = CAddonMgr::Get().GetExtValue(elem, "label"); + auto menuId = CAddonMgr::Get().GetExtValue(elem, "@id"); + + if (menuId.empty()) + { + //anonymous group. create a new unique internal id. + std::stringstream ss; + ss << ID() << ++anonGroupCount; + menuId = ss.str(); + } + + m_items.push_back(CContextMenuItem::CreateGroup(menuLabel, parent, menuId)); + + ELEMENTS subMenus; + if (CAddonMgr::Get().GetExtElements(elem, "menu", subMenus)) + for (const auto& subMenu : subMenus) + ParseMenu(subMenu, menuId, anonGroupCount); + + ELEMENTS items; + if (CAddonMgr::Get().GetExtElements(elem, "item", items)) + { + for (const auto& item : items) + { + auto label = CAddonMgr::Get().GetExtValue(item, "label"); + auto visCondition = CAddonMgr::Get().GetExtValue(item, "visible"); + auto library = CAddonMgr::Get().GetExtValue(item, "@library"); + + if (!label.empty() && !library.empty() && !visCondition.empty()) + { + auto menu = CContextMenuItem::CreateItem( + label, + menuId, + URIUtils::AddFileToFolder(Path(), library), + g_infoManager.Register(visCondition, 0)); + + m_items.push_back(menu); + } + } + } +} + +std::vector<CContextMenuItem> CContextMenuAddon::GetItems() +{ + //Return a copy which owns `this` + std::vector<CContextMenuItem> ret = m_items; + for (CContextMenuItem& menuItem : ret) + menuItem.m_addon = this->shared_from_this(); + return ret; +} + +} diff --git a/xbmc/addons/ContextMenuAddon.h b/xbmc/addons/ContextMenuAddon.h new file mode 100644 index 0000000000..887a9fc310 --- /dev/null +++ b/xbmc/addons/ContextMenuAddon.h @@ -0,0 +1,47 @@ +#pragma once +/* + * Copyright (C) 2013-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/>. + * + */ + +#include <list> +#include <memory> +#include "Addon.h" + +class CContextMenuItem; +typedef struct cp_cfg_element_t cp_cfg_element_t; + + +namespace ADDON +{ + class CContextMenuAddon : public CAddon + { + public: + CContextMenuAddon(const cp_extension_t *ext); + CContextMenuAddon(const AddonProps &props); + virtual ~CContextMenuAddon(); + + std::vector<CContextMenuItem> GetItems(); + + private: + void ParseMenu(cp_cfg_element_t* elem, const std::string& parent, int& anonGroupCount); + std::vector<CContextMenuItem> m_items; + }; + + typedef std::shared_ptr<CContextMenuAddon> ContextItemAddonPtr; +} diff --git a/xbmc/addons/Makefile b/xbmc/addons/Makefile index d8c0860880..29926f27ea 100644 --- a/xbmc/addons/Makefile +++ b/xbmc/addons/Makefile @@ -11,7 +11,7 @@ SRCS=Addon.cpp \ AddonStatusHandler.cpp \ AddonVersion.cpp \ AudioEncoder.cpp \ - ContextItemAddon.cpp \ + ContextMenuAddon.cpp \ AudioDecoder.cpp \ GUIDialogAddonInfo.cpp \ GUIDialogAddonSettings.cpp \ diff --git a/xbmc/dialogs/GUIDialogFavourites.cpp b/xbmc/dialogs/GUIDialogFavourites.cpp index f92fe7565f..d49b774b10 100644 --- a/xbmc/dialogs/GUIDialogFavourites.cpp +++ b/xbmc/dialogs/GUIDialogFavourites.cpp @@ -151,7 +151,7 @@ void CGUIDialogFavourites::OnPopupMenu(int item) else if (button == 5) OnSetThumb(item); else if (button >= CONTEXT_BUTTON_FIRST_ADDON) - CContextMenuManager::Get().Execute(button, itemPtr); + CContextMenuManager::Get().OnClick(button, itemPtr); } void CGUIDialogFavourites::OnMoveItem(int item, int amount) diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp index 07ebd764d3..e9e1969a74 100644 --- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp @@ -1006,7 +1006,7 @@ int CGUIDialogVideoInfo::ManageVideoItem(const CFileItemPtr &item) buttons.Add(CONTEXT_BUTTON_DELETE, 646); - CContextMenuManager::Get().AddVisibleItems(item, buttons, CONTEXT_MENU_GROUP_MANAGE); + CContextMenuManager::Get().AddVisibleItems(item, buttons, CContextMenuManager::MANAGE); bool result = false; int button = CGUIDialogContextMenu::ShowAndGetChoice(buttons); @@ -1070,7 +1070,7 @@ int CGUIDialogVideoInfo::ManageVideoItem(const CFileItemPtr &item) break; default: - result = CContextMenuManager::Get().Execute(button, item); + result = CContextMenuManager::Get().OnClick(button, item); break; } } diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp index 91bb3aa335..f2d870c86d 100644 --- a/xbmc/windows/GUIMediaWindow.cpp +++ b/xbmc/windows/GUIMediaWindow.cpp @@ -1617,7 +1617,7 @@ bool CGUIMediaWindow::OnContextButton(int itemNumber, CONTEXT_BUTTON button) break; } if (button >= CONTEXT_BUTTON_FIRST_ADDON) - return CContextMenuManager::Get().Execute(button, m_vecItems->Get(itemNumber)); + return CContextMenuManager::Get().OnClick(button, m_vecItems->Get(itemNumber)); return false; } diff --git a/xbmc/windows/GUIWindowLoginScreen.cpp b/xbmc/windows/GUIWindowLoginScreen.cpp index 00e39450c0..80e9dd3209 100644 --- a/xbmc/windows/GUIWindowLoginScreen.cpp +++ b/xbmc/windows/GUIWindowLoginScreen.cpp @@ -257,7 +257,7 @@ bool CGUIWindowLoginScreen::OnPopupMenu(int iItem) m_vecItems->Get(iItem)->Select(bSelect); if (choice >= CONTEXT_BUTTON_FIRST_ADDON) - return CContextMenuManager::Get().Execute(choice, pItem); + return CContextMenuManager::Get().OnClick(choice, pItem); return false; } |