Welcome to a new installment of the plugins tutorial! Todays issue will cover menu modifications. This allows you to add new menu options for features you introduce with your plugin.
GTK menu concepts
Before diving into the example code we need to cover some theory. GTK3 provides several APIs to build menus but for Liferea plugins only one of them is exposed: the
GtkUIManager.
In short the GtkUIManager allows adding UI elements (menus ,toolbars, accelerators) using XML like this:
<ui>
<menubar>
<menu name="FileMenu" action="FileMenuAction">
<menuitem name="New" action="New2Action" />
</menu>
</ui>
The above snippet defines an menu item that you can merged into the UI by calling a method like
gtk_ui_manager_add_ui_from_string().
Note that above definition only says that there ought to be a menu action with internal action name "New2Action". So we still have to define this active and bind a callback.
Extending a menu in PyGI
Now how do we extend a Liferea menu? First we get the GtkUIManager:
self._ui_manager = self.shell.get_property("ui-manager")
Now we can add an XML snippet describing a menu
self._ui_manager.add_ui_from_string(
"""<ui>
<menubar name='MainwindowMenubar'>
<menu action='ToolsMenu'>
<menuitem action='MyPluginMenuEntry'/>
</menu>
</menubar>
</ui>"""
)
Please note that the GtkUIManager property is only exposed starting with Liferea version 1.12.2!
And as said above we need to add an action for this menu item. As actions can only be added in groups using a GtkActionGroup we need to create one first, insert the action and finally tell the GtkUIManager about the action group:
self._action = Gtk.Action('MyPluginMenuEntry', 'Awesome Function', 'Run a really awesome function', None)
self._action.connect("activate", self._do_action)
self._actiongroup = Gtk.ActionGroup("MyPluginActions")
self._actiongroup.add_action(self._action)
self._ui_manager.insert_action_group(self._actiongroup)
Available Menus
You probably noticed the "ToolsMenu" and "MainwindowMenubar" ids in the XML snippet above. Here is a list of all menu ids in 1.12 which also can be found in
src/ui/liferea_shell.c.
Name |
Description |
FeedMenu | All actions regarding subscriptions and the feed list |
ItemMenu | All actions regarding the item list |
ViewMenu | All actions controlling reading layout |
ToolsMenu | The menu to access preferences and update status |
SearchMenu | All actions for finding stuff |
HelpMenu | The place to go for help |
Complete Solution
Everything put together in a plugin could look like this:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import GObject, Liferea, Gtk
class AppActivatable(GObject.Object, Liferea.ShellActivatable):
__gtype_name__ = "MyPluginAppActivatable"
shell = GObject.property(type=Liferea.Shell)
def __init__(self):
GObject.Object.__init__(self)
def do_activate(self):
self._action = Gtk.Action('MyPluginMenuEntry', 'Awesome Function', 'Run a really awesome function', None)
self._action.connect("activate", self._do_action)
self._actiongroup = Gtk.ActionGroup("MyPluginActions")
self._actiongroup.add_action(self._action)
self._ui_manager = self.shell.get_property("ui-manager")
self._ui_manager.insert_action_group(self._actiongroup)
self._ui_manager.add_ui_from_string(
"""<ui>
<menubar name='MainwindowMenubar'>
<menu action='ToolsMenu'>
<menuitem action='MyPluginMenuEntry'/>
</menu>
</menubar>
</ui>"""
)
def _do_action(self, action, data=None):
print("Action triggered")
For a real world example have a look at
https://github.com/lwindolf/liferea/blob/master/plugins/plugin-installer.py
Related
Also check out the previous plugin tutorial posts