Added plug-in deactivation mechanism, which allows plug-ins to clean up after themselves (eg. disconnecting handlers made in GUI); GUI extension points handlers are removed from list.

Updated Length Notifier plug-in so that it can be properly deactivated.
This commit is contained in:
Mateusz Biliński 2008-06-03 13:40:27 +00:00
parent 77f10031f1
commit 654e157eff
2 changed files with 51 additions and 12 deletions

View File

@ -74,9 +74,17 @@ length of message is exceeded.'''
if self.jid_is_ok(jid):
d = {'prev_color' : None}
tv = chat_control.msg_textview
b = tv.get_buffer()
h_id = b.connect('changed', self.textview_length_warning, chat_control)
tb = tv.get_buffer()
h_id = tb.connect('changed', self.textview_length_warning, chat_control)
d['h_id'] = h_id
t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
if t:
len_t = len(t)
if len_t>self.MESSAGE_WARNING_LENGTH:
d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
tv.modify_base(gtk.STATE_NORMAL, self.WARNING_COLOR)
chat_control.length_notifier_plugin_data = d
return True
@ -86,9 +94,10 @@ length of message is exceeded.'''
@log_calls('LengthNotifierPlugin')
def disconnect_from_chat_control(self, chat_control):
d = chat_control.length_notifier_plugin_data
chat_control.msg_textview.get_buffer().disconnect(d['h_id'])
tv = chat_control.msg_textview
tv.get_buffer().disconnect(d['h_id'])
if d['prev_color']:
tv.modify_base(gtk.STATE_NORMAL, self.PREV_COLOR)
tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
@log_calls('LengthNotifierPlugin')
def jid_is_ok(self, jid):

View File

@ -49,14 +49,22 @@ class PluginManager(object):
:todo: add list of available GUI extension points
:todo: implement mechanism to dynamically load plugins where GUI extension
points have been already called (i.e. when plugin is activated
after GUI object creation)
after GUI object creation). [DONE?]
:todo: implement mechanism to dynamically deactive plugins (call plugin's
deactivation handler)
deactivation handler) [DONE?]
:todo: when plug-in is deactivated all GUI extension points are removed
from `PluginManager.gui_extension_points_handlers`. But when
object that invoked GUI extension point is abandoned by Gajim, eg.
closed ChatControl object, the reference to called GUI extension
points is still in `PluginManager.gui_extension_points`. These
should be removed, so that object can be destroyed by Python.
Possible solution: add call to clean up method in classes
'destructors' (classes that register GUI extension points)
'''
__metaclass__ = Singleton
@log_calls('PluginManager')
#@log_calls('PluginManager')
def __init__(self):
self.plugins = []
'''
@ -68,7 +76,7 @@ class PluginManager(object):
'''
self.active_plugins = []
'''
Objectsof active plugins.
Instance objects of active plugins.
These are object instances of classes held `plugins`, but only those
that were activated.
@ -90,7 +98,7 @@ class PluginManager(object):
log.debug('plugins: %s'%(self.plugins))
#self._activate_all_plugins()
self.activate_all_plugins()
log.debug('active: %s'%(self.active_plugins))
@ -133,7 +141,7 @@ class PluginManager(object):
handlers[0](*args)
@log_calls('PluginManager')
def _activate_plugin(self, plugin):
def activate_plugin(self, plugin):
'''
:param plugin: plugin to be activated
:type plugin: class object of `GajimPlugin` subclass
@ -151,6 +159,28 @@ class PluginManager(object):
return success
def deactivate_plugin(self, plugin_object):
# detaching plug-in from handler GUI extension points (calling
# cleaning up method that must be provided by plug-in developer
# for each handled GUI extension point)
for gui_extpoint_name, gui_extpoint_handlers in \
plugin_object.gui_extension_points.iteritems():
for gui_extension_point_args in self.gui_extension_points[gui_extpoint_name]:
gui_extpoint_handlers[1](*gui_extension_point_args)
# remove GUI extension points handlers (provided by plug-in) from
# handlers list
for gui_extpoint_name, gui_extpoint_handlers in \
plugin_object.gui_extension_points.iteritems():
self.gui_extension_points_handlers[gui_extpoint_name].remove(gui_extpoint_handlers)
# removing plug-in from active plug-ins list
self.active_plugins.remove(plugin_object)
def deactivate_all_plugins(self):
for plugin_object in self.active_plugins:
self.deactivate_plugin(plugin_object)
@log_calls('PluginManager')
def _add_gui_extension_points_handlers_from_plugin(self, plugin_object):
for gui_extpoint_name, gui_extpoint_handlers in \
@ -167,7 +197,7 @@ class PluginManager(object):
gui_extpoint_handlers[0](*gui_extension_point_args)
@log_calls('PluginManager')
def _activate_all_plugins(self):
def activate_all_plugins(self):
'''
Activates all plugins in `plugins`.
@ -175,7 +205,7 @@ class PluginManager(object):
'''
self.active_plugins = []
for plugin in self.plugins:
self._activate_plugin(plugin)
self.activate_plugin(plugin)
@staticmethod
@log_calls('PluginManager')