Switch the plugin prefs pane back to live loading/unloading of plugins without silly compromises
This commit is contained in:
parent
70a66ee218
commit
45a9c26cf2
|
@ -28,16 +28,20 @@ import os
|
||||||
import borg
|
import borg
|
||||||
from config import Config
|
from config import Config
|
||||||
from util import dbg, err, get_config_dir
|
from util import dbg, err, get_config_dir
|
||||||
|
from terminator import Terminator
|
||||||
|
|
||||||
class Plugin(object):
|
class Plugin(object):
|
||||||
"""Definition of our base plugin class"""
|
"""Definition of our base plugin class"""
|
||||||
capabilities = None
|
capabilities = None
|
||||||
is_permanent = None
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Class initialiser."""
|
"""Class initialiser."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def unload(self):
|
||||||
|
"""Prepare to be unloaded"""
|
||||||
|
pass
|
||||||
|
|
||||||
class PluginRegistry(borg.Borg):
|
class PluginRegistry(borg.Borg):
|
||||||
"""Definition of a class to store plugin instances"""
|
"""Definition of a class to store plugin instances"""
|
||||||
available_plugins = None
|
available_plugins = None
|
||||||
|
@ -128,29 +132,18 @@ for %s' % (len(self.instances), capability))
|
||||||
not"""
|
not"""
|
||||||
return(self.instances.has_key(plugin))
|
return(self.instances.has_key(plugin))
|
||||||
|
|
||||||
def is_permanent(self, plugin):
|
|
||||||
"""Return a boolean value indicating whether a plugin is believed to be
|
|
||||||
permanent. This is impossible to determine for plugins that haven't
|
|
||||||
been loaded, so they will report as not being permanent until they are
|
|
||||||
loaded"""
|
|
||||||
if plugin not in self.instances:
|
|
||||||
return(False)
|
|
||||||
else:
|
|
||||||
return(self.instances[plugin].is_permanent)
|
|
||||||
|
|
||||||
def enable(self, plugin):
|
def enable(self, plugin):
|
||||||
"""Enable a plugin"""
|
"""Enable a plugin"""
|
||||||
|
if plugin in self.instances:
|
||||||
|
err("Cannot enable plugin %s, already enabled" % plugin)
|
||||||
dbg("Enabling %s" % plugin)
|
dbg("Enabling %s" % plugin)
|
||||||
if plugin not in self.instances:
|
self.instances[plugin] = self.available_plugins[plugin]()
|
||||||
self.instances[plugin] = self.available_plugins[plugin]()
|
|
||||||
|
|
||||||
def disable(self, plugin):
|
def disable(self, plugin):
|
||||||
"""Disable a plugin"""
|
"""Disable a plugin"""
|
||||||
if self.instances[plugin].is_permanent:
|
dbg("Disabling %s" % plugin)
|
||||||
dbg("Refusing to disable permanent plugin %s" % plugin)
|
self.instances[plugin].unload()
|
||||||
else:
|
del(self.instances[plugin])
|
||||||
dbg("Disabling %s" % plugin)
|
|
||||||
del(self.instances[plugin])
|
|
||||||
|
|
||||||
# This is where we should define a base class for each type of plugin we
|
# This is where we should define a base class for each type of plugin we
|
||||||
# support
|
# support
|
||||||
|
@ -162,12 +155,28 @@ class URLHandler(Plugin):
|
||||||
capabilities = ['url_handler']
|
capabilities = ['url_handler']
|
||||||
handler_name = None
|
handler_name = None
|
||||||
match = None
|
match = None
|
||||||
is_permanent = True
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Class initialiser"""
|
||||||
|
Plugin.__init__(self)
|
||||||
|
terminator = Terminator()
|
||||||
|
for terminal in terminator.terminals:
|
||||||
|
terminal.match_add(self.handler_name, self.match)
|
||||||
|
|
||||||
def callback(self, url):
|
def callback(self, url):
|
||||||
"""Callback to transform the enclosed URL"""
|
"""Callback to transform the enclosed URL"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def unload(self):
|
||||||
|
"""Handle being removed"""
|
||||||
|
if not self.match:
|
||||||
|
err('unload called without self.handler_name being set')
|
||||||
|
return
|
||||||
|
terminator = Terminator()
|
||||||
|
for terminal in terminator.terminals:
|
||||||
|
print self.handler_name
|
||||||
|
terminal.match_remove(self.handler_name)
|
||||||
|
|
||||||
# MenuItem - This is able to execute code during the construction of the
|
# MenuItem - This is able to execute code during the construction of the
|
||||||
# context menu of a Terminal.
|
# context menu of a Terminal.
|
||||||
class MenuItem(Plugin):
|
class MenuItem(Plugin):
|
||||||
|
|
|
@ -2865,51 +2865,32 @@
|
||||||
<object class="GtkHBox" id="hbox7">
|
<object class="GtkHBox" id="hbox7">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkVBox" id="vbox12">
|
<object class="GtkTreeView" id="pluginlist">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="model">PluginListStore</property>
|
||||||
|
<property name="hadjustment">adjustment2</property>
|
||||||
|
<property name="vadjustment">adjustment3</property>
|
||||||
|
<property name="search_column">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeView" id="pluginlist">
|
<object class="GtkTreeViewColumn" id="plugincolumn1">
|
||||||
<property name="visible">True</property>
|
<property name="title">Plugin</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="clickable">True</property>
|
||||||
<property name="model">PluginListStore</property>
|
|
||||||
<property name="hadjustment">adjustment2</property>
|
|
||||||
<property name="vadjustment">adjustment3</property>
|
|
||||||
<property name="search_column">0</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="plugincolumn1">
|
<object class="GtkCellRendererToggle" id="cellrenderertext15">
|
||||||
<property name="title">Plugin</property>
|
<signal name="toggled" handler="on_plugin_toggled"/>
|
||||||
<property name="clickable">True</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkCellRendererToggle" id="cellrenderertext15">
|
|
||||||
<signal name="toggled" handler="on_plugin_toggled"/>
|
|
||||||
</object>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="active">1</attribute>
|
|
||||||
</attributes>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkCellRendererText" id="cellrenderertext16"/>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="text">0</attribute>
|
|
||||||
</attributes>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="active">1</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText" id="cellrenderertext16"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">0</attribute>
|
||||||
|
</attributes>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="label13">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes">Plugins will be enabled/disabled after restarting Terminator</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">False</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
|
|
|
@ -1025,6 +1025,13 @@ class PrefsEditor:
|
||||||
model = treeview.get_model()
|
model = treeview.get_model()
|
||||||
plugin = model[path][0]
|
plugin = model[path][0]
|
||||||
|
|
||||||
|
if not self.plugins[plugin]:
|
||||||
|
# Plugin is currently disabled, load it
|
||||||
|
self.registry.enable(plugin)
|
||||||
|
else:
|
||||||
|
# Plugin is currently enabled, unload it
|
||||||
|
self.registry.disable(plugin)
|
||||||
|
|
||||||
self.plugins[plugin] = not self.plugins[plugin]
|
self.plugins[plugin] = not self.plugins[plugin]
|
||||||
# Update the treeview
|
# Update the treeview
|
||||||
model[path][1] = self.plugins[plugin]
|
model[path][1] = self.plugins[plugin]
|
||||||
|
|
|
@ -268,12 +268,31 @@ class Terminal(gtk.VBox):
|
||||||
for urlplugin in plugins:
|
for urlplugin in plugins:
|
||||||
name = urlplugin.handler_name
|
name = urlplugin.handler_name
|
||||||
match = urlplugin.match
|
match = urlplugin.match
|
||||||
|
if name in self.matches:
|
||||||
|
dbg('Terminal::update_matches: refusing to add \
|
||||||
|
duplicate match %s' % name)
|
||||||
|
continue
|
||||||
self.matches[name] = self.vte.match_add(match)
|
self.matches[name] = self.vte.match_add(match)
|
||||||
dbg('Terminal::update_matches: added plugin URL handler \
|
dbg('Terminal::update_matches: added plugin URL handler \
|
||||||
for %s (%s)' % (name, urlplugin.__class__.__name__))
|
for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
err('Terminal::update_url_matches: %s' % ex)
|
err('Terminal::update_url_matches: %s' % ex)
|
||||||
|
|
||||||
|
def match_add(self, name, match):
|
||||||
|
"""Register a URL match"""
|
||||||
|
if name in self.matches:
|
||||||
|
err('Terminal::match_add: Refusing to create duplicate match %s' % name)
|
||||||
|
return
|
||||||
|
self.matches[name] = self.vte.match_add(match)
|
||||||
|
|
||||||
|
def match_remove(self, name):
|
||||||
|
"""Remove a previously registered URL match"""
|
||||||
|
if name not in self.matches:
|
||||||
|
err('Terminal::match_remove: Unable to remove non-existent match %s' % name)
|
||||||
|
return
|
||||||
|
self.vte.match_remove(self.matches[name])
|
||||||
|
del(self.matches[name])
|
||||||
|
|
||||||
def connect_signals(self):
|
def connect_signals(self):
|
||||||
"""Connect all the gtk signals and drag-n-drop mechanics"""
|
"""Connect all the gtk signals and drag-n-drop mechanics"""
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue