Skip to content

Commit

Permalink
[ADDONS] Context Menu Addons System
Browse files Browse the repository at this point in the history
  • Loading branch information
Fice authored and tamland committed Mar 2, 2015
1 parent 2951068 commit b30c551
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 5 deletions.
1 change: 1 addition & 0 deletions addons/xbmc.python/addon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
<extension-point id="weather" schema="script.xsd"/>
<extension-point id="library" schema="script.xsd"/>
<extension-point id="plugin" schema="pluginsource.xsd"/>
<extension-point id="context.item" schema="contextitem.xsd"/>
</addon>
29 changes: 29 additions & 0 deletions addons/xbmc.python/contextitem.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<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: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:simpleType name="simpleIdentifier">
<xs:restriction base="xs:string">
<xs:pattern value="[^.]+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

8 changes: 7 additions & 1 deletion language/English/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -12307,7 +12307,13 @@ msgctxt "#24024"
msgid "Add-on disabled"
msgstr ""

#empty strings from id 24025 to 24026
#. Used as the type name for context item addons
#: xbmc/addons/Addons.cpp
msgctxt "#24025"
msgid "Context Items"
msgstr ""

#empty string with id 24026

#: xbmc/addons/Addon.cpp
msgctxt "#24027"
Expand Down
116 changes: 116 additions & 0 deletions xbmc/ContextMenuManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* 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 "ContextMenuManager.h"
#include "addons/Addon.h"
#include "addons/AddonManager.h"
#include "addons/ContextItemAddon.h"
#include "addons/IAddon.h"
#include "interfaces/generic/ScriptInvocationManager.h"
#include "interfaces/python/ContextItemAddonInvoker.h"
#include "interfaces/python/XBPython.h"
#include "Util.h"
#include "utils/log.h"
#include "video/dialogs/GUIDialogVideoInfo.h"

using namespace ADDON;

typedef std::map<unsigned int, ContextItemAddonPtr>::value_type ValueType;


CContextMenuManager::CContextMenuManager()
: m_iCurrentContextId(CONTEXT_BUTTON_FIRST_ADDON)
{
Init();
}

CContextMenuManager& CContextMenuManager::Get()
{
static CContextMenuManager mgr;
return mgr;
}

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));
}
}

void CContextMenuManager::Register(const ContextItemAddonPtr& cm)
{
if (!cm)
return;
m_contextAddons[m_iCurrentContextId++] = cm;
}

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;
}

ContextItemAddonPtr CContextMenuManager::GetContextItemByID(unsigned int id)
{
auto it = m_contextAddons.find(id);
if (it != m_contextAddons.end())
return it->second;
return ContextItemAddonPtr();
}

void CContextMenuManager::AddVisibleItems(const CFileItemPtr& item, CContextButtons& list, const std::string& parent /* = "" */)
{
if (!item)
return;

for (const auto& kv : m_contextAddons)
{
if (kv.second->GetParent() == parent && kv.second->IsVisible(item))
list.push_back(std::make_pair(kv.first, kv.second->GetLabel()));
}
}

bool CContextMenuManager::Execute(unsigned int id, const CFileItemPtr& item)
{
if (!item)
return false;

const ContextItemAddonPtr addon = GetContextItemByID(id);
if (!addon || !addon->IsVisible(item))
return false;

LanguageInvokerPtr invoker(new CContextItemAddonInvoker(&g_pythonParser, item));
return (CScriptInvocationManager::Get().ExecuteAsync(addon->LibPath(), invoker, addon) != -1);
}

78 changes: 78 additions & 0 deletions xbmc/ContextMenuManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#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 <map>
#include "addons/ContextItemAddon.h"
#include "dialogs/GUIDialogContextMenu.h"

#define CONTEXT_MENU_GROUP_MANAGE "kodi.core.manage"

class CContextMenuManager
{
public:
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
*/
bool Execute(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.
*/
void AddVisibleItems(const CFileItemPtr& item, CContextButtons& list, const std::string& parent = "");

/*!
* \brief Adds a context item to this manager.
* NOTE: only 'enabled' context addons should be added.
*/
void Register(const ADDON::ContextItemAddonPtr& cm);

/*!
* \brief Removes a context addon from this manager.
*/
bool Unregister(const ADDON::ContextItemAddonPtr& cm);

private:
CContextMenuManager();
CContextMenuManager(const CContextMenuManager&);
CContextMenuManager const& operator=(CContextMenuManager const&);
virtual ~CContextMenuManager() {}

void Init();

/*!
* \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;
};
1 change: 1 addition & 0 deletions xbmc/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ SRCS=Application.cpp \
Autorun.cpp \
AutoSwitch.cpp \
BackgroundInfoLoader.cpp \
ContextMenuManager.cpp \
CompileInfo.cpp \
CueDocument.cpp \
DatabaseManager.cpp \
Expand Down
3 changes: 3 additions & 0 deletions xbmc/addons/Addon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ static const TypeMapping types[] =
{"xbmc.python.library", ADDON_SCRIPT_LIBRARY, 24081, "DefaultAddonHelper.png" },
{"xbmc.python.module", ADDON_SCRIPT_MODULE, 24082, "DefaultAddonLibrary.png" },
{"xbmc.subtitle.module", ADDON_SUBTITLE_MODULE, 24012, "DefaultAddonSubtitles.png" },
{"kodi.context.item", ADDON_CONTEXT_ITEM, 24025, "DefaultAddonContextItem.png" },
{"xbmc.gui.skin", ADDON_SKIN, 166, "DefaultAddonSkin.png" },
{"xbmc.webinterface", ADDON_WEB_INTERFACE, 199, "DefaultAddonWebSkin.png" },
{"xbmc.addon.repository", ADDON_REPOSITORY, 24011, "DefaultAddonRepository.png" },
Expand Down Expand Up @@ -360,6 +361,7 @@ void CAddon::BuildLibName(const cp_extension_t *extension)
case ADDON_SUBTITLE_MODULE:
case ADDON_PLUGIN:
case ADDON_SERVICE:
case ADDON_CONTEXT_ITEM:
ext = ADDON_PYTHON_EXT;
break;
default:
Expand Down Expand Up @@ -394,6 +396,7 @@ void CAddon::BuildLibName(const cp_extension_t *extension)
case ADDON_SERVICE:
case ADDON_REPOSITORY:
case ADDON_AUDIOENCODER:
case ADDON_CONTEXT_ITEM:
{
std::string temp = CAddonMgr::Get().GetExtValue(extension->configuration, "@library");
m_strLibName = temp;
Expand Down
3 changes: 2 additions & 1 deletion xbmc/addons/Addon.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ class CAddon : public IAddon
bool m_settingsLoaded;
bool m_userSettingsLoaded;

virtual void ClearStrings();
private:
friend class CAddonMgr;
AddonProps m_props;
Expand All @@ -248,7 +249,7 @@ class CAddon : public IAddon
void Disable() { m_enabled = false; ClearStrings();}

virtual bool LoadStrings();
virtual void ClearStrings();

bool m_hasStrings;
bool m_checkedStrings;
bool m_hasSettings;
Expand Down
7 changes: 5 additions & 2 deletions xbmc/addons/AddonDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "utils/StringUtils.h"
#include "XBDateTime.h"
#include "dbwrappers/dataset.h"
#include "addons/ContextItemAddon.h"

using namespace ADDON;
using namespace std;
Expand Down Expand Up @@ -620,7 +621,8 @@ bool CAddonDatabase::DisableAddon(const std::string &addonID, bool disable /* =
// If the addon is a special, call the disabled handler
AddonPtr addon;
if ((CAddonMgr::Get().GetAddon(addonID, addon, ADDON_SERVICE, false)
|| CAddonMgr::Get().GetAddon(addonID, addon, ADDON_PVRDLL, false)) && addon)
|| CAddonMgr::Get().GetAddon(addonID, addon, ADDON_PVRDLL, false)
|| CAddonMgr::Get().GetAddon(addonID, addon, ADDON_CONTEXT_ITEM, false)) && addon)
addon->OnDisabled();

return true;
Expand All @@ -638,7 +640,8 @@ bool CAddonDatabase::DisableAddon(const std::string &addonID, bool disable /* =
// If the addon is a special, call the enabled handler
AddonPtr addon;
if ((CAddonMgr::Get().GetAddon(addonID, addon, ADDON_SERVICE, false)
|| CAddonMgr::Get().GetAddon(addonID, addon, ADDON_PVRDLL, false)) && addon)
|| CAddonMgr::Get().GetAddon(addonID, addon, ADDON_PVRDLL, false)
|| CAddonMgr::Get().GetAddon(addonID, addon, ADDON_CONTEXT_ITEM, false)) && addon)
addon->OnEnabled();
}
}
Expand Down
5 changes: 5 additions & 0 deletions xbmc/addons/AddonManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "Repository.h"
#include "Skin.h"
#include "Service.h"
#include "ContextItemAddon.h"
#include "Util.h"
#include "addons/Webinterface.h"

Expand Down Expand Up @@ -173,6 +174,8 @@ AddonPtr CAddonMgr::Factory(const cp_extension_t *props)
return AddonPtr(new CAddonLibrary(props));
case ADDON_REPOSITORY:
return AddonPtr(new CRepository(props));
case ADDON_CONTEXT_ITEM:
return AddonPtr(new CContextItemAddon(props));
default:
break;
}
Expand Down Expand Up @@ -682,6 +685,8 @@ AddonPtr CAddonMgr::AddonFromProps(AddonProps& addonProps)
return AddonPtr(new CAudioEncoder(addonProps));
case ADDON_REPOSITORY:
return AddonPtr(new CRepository(addonProps));
case ADDON_CONTEXT_ITEM:
return AddonPtr(new CContextItemAddon(addonProps));
default:
break;
}
Expand Down
Loading

0 comments on commit b30c551

Please sign in to comment.