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
|
||||
from config import Config
|
||||
from util import dbg, err, get_config_dir
|
||||
from terminator import Terminator
|
||||
|
||||
class Plugin(object):
|
||||
"""Definition of our base plugin class"""
|
||||
capabilities = None
|
||||
is_permanent = None
|
||||
|
||||
def __init__(self):
|
||||
"""Class initialiser."""
|
||||
pass
|
||||
|
||||
def unload(self):
|
||||
"""Prepare to be unloaded"""
|
||||
pass
|
||||
|
||||
class PluginRegistry(borg.Borg):
|
||||
"""Definition of a class to store plugin instances"""
|
||||
available_plugins = None
|
||||
|
@ -128,29 +132,18 @@ for %s' % (len(self.instances), capability))
|
|||
not"""
|
||||
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):
|
||||
"""Enable a plugin"""
|
||||
if plugin in self.instances:
|
||||
err("Cannot enable plugin %s, already enabled" % 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):
|
||||
"""Disable a plugin"""
|
||||
if self.instances[plugin].is_permanent:
|
||||
dbg("Refusing to disable permanent plugin %s" % plugin)
|
||||
else:
|
||||
dbg("Disabling %s" % plugin)
|
||||
del(self.instances[plugin])
|
||||
dbg("Disabling %s" % plugin)
|
||||
self.instances[plugin].unload()
|
||||
del(self.instances[plugin])
|
||||
|
||||
# This is where we should define a base class for each type of plugin we
|
||||
# support
|
||||
|
@ -162,12 +155,28 @@ class URLHandler(Plugin):
|
|||
capabilities = ['url_handler']
|
||||
handler_name = 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):
|
||||
"""Callback to transform the enclosed URL"""
|
||||
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
|
||||
# context menu of a Terminal.
|
||||
class MenuItem(Plugin):
|
||||
|
|
|
@ -2865,51 +2865,32 @@
|
|||
<object class="GtkHBox" id="hbox7">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox12">
|
||||
<object class="GtkTreeView" id="pluginlist">
|
||||
<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>
|
||||
<object class="GtkTreeView" id="pluginlist">
|
||||
<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>
|
||||
<object class="GtkTreeViewColumn" id="plugincolumn1">
|
||||
<property name="title">Plugin</property>
|
||||
<property name="clickable">True</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="plugincolumn1">
|
||||
<property name="title">Plugin</property>
|
||||
<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 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>
|
||||
<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>
|
||||
</object>
|
||||
<packing>
|
||||
|
|
|
@ -1025,6 +1025,13 @@ class PrefsEditor:
|
|||
model = treeview.get_model()
|
||||
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]
|
||||
# Update the treeview
|
||||
model[path][1] = self.plugins[plugin]
|
||||
|
|
|
@ -268,12 +268,31 @@ class Terminal(gtk.VBox):
|
|||
for urlplugin in plugins:
|
||||
name = urlplugin.handler_name
|
||||
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)
|
||||
dbg('Terminal::update_matches: added plugin URL handler \
|
||||
for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
except Exception, 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):
|
||||
"""Connect all the gtk signals and drag-n-drop mechanics"""
|
||||
|
||||
|
|
Loading…
Reference in New Issue