diff --git a/src/core.py b/src/core.py index 1f21e36d..8e85ce90 100644 --- a/src/core.py +++ b/src/core.py @@ -33,6 +33,7 @@ import multiuserchat as muc import tabs import xhtml +import events import pubsub import windows import connection @@ -81,12 +82,6 @@ class Core(object): User interface using ncurses """ - # dict containing the name of the internal events - # used with the plugins, the key is the name of the event - # and the value is the number of arguments the handler must take - internal_events = { - 'enter': 2, - } def __init__(self): # All uncaught exception are given to this callback, instead # of being displayed on the screen and exiting the program. @@ -94,6 +89,7 @@ class Core(object): self.status = Status(show=None, message='') sys.excepthook = self.on_exception self.running = True + self.events = events.EventHandler() self.xmpp = singleton.Singleton(connection.Connection) self.remote_fifo = None # a unique buffer used to store global informations @@ -180,7 +176,6 @@ class Core(object): self.timed_events = set() - self.connected_events = {} self.autoload_plugins() def autoload_plugins(self): @@ -213,58 +208,6 @@ class Core(object): 'Just press Ctrl-n.' \ )) self.refresh_window() - - def connect(self, event, handler): - """ - Connect an handler to an internal event of poezio - (eg "enter pressed in a chattab") - """ - # Fail if the method doesn’t take at least the good number of arguments - # or if the event is unknown - if not event in self.internal_events \ - or len(getargspec(handler).args) < self.internal_events[event]: - return False - - module_name = handler.__module__ - if not event in self.connected_events: - self.connected_events[event] = {} - if not module_name in self.connected_events[event]: - self.connected_events[event][module_name] = [] - - self.connected_events[event][module_name].append(handler) - return True - - def run_event(self, event, **kwargs): - """ - Call the handlers associated with an event - """ - if event in self.connected_events: - for module in self.connected_events[event]: - for handler in self.connected_events[event][module]: - try: - handler(**kwargs) - except: - import traceback - tp = traceback.format_exc() - module_name = handler.__name__ - log.debug('ERROR: in plugin %s, \n%s' % (module_name, tp)) - - def disconnect(self, event, handler): - """ - Disconnect a handler from an event - """ - if not event in self.internal_events: - return False - - module_name = getmodule(handler).__name__ - if not event in self.connected_events: - return False - if not module_name in self.connected_events[event]: - return False - - self.connected_events[event][module_name].remove(handler) - return True - def resize_global_information_win(self): """ Resize the global_information_win only once at each resize. @@ -272,7 +215,6 @@ class Core(object): self.information_win.resize(self.information_win_size, tabs.Tab.width, tabs.Tab.height - 2 - self.information_win_size, 0) - def resize_global_info_bar(self): """ Resize the GlobalInfoBar only once at each resize diff --git a/src/plugin.py b/src/plugin.py index a8eb5934..0b4f3f3a 100644 --- a/src/plugin.py +++ b/src/plugin.py @@ -84,3 +84,9 @@ class BasePlugin(object, metaclass=SafetyMetaclass): def del_event_handler(self, event_name, handler): return self.plugin_manager.del_event_handler(self.__module__, event_name, handler) + + def add_poezio_event_handler(self, event_name, handler, first=True, last=False, position=None): + return self.plugin_manager.add_poezio_event_handler(self.__module__, event_name, handler, first, last, position) + + def del_poezio_event_handler(self, event_name, handler): + return self.plugin_manager.del_poezio_event_handler(self.__module__, event_name, handler) diff --git a/src/plugin_manager.py b/src/plugin_manager.py index 5bd6d75b..37db3d13 100644 --- a/src/plugin_manager.py +++ b/src/plugin_manager.py @@ -34,6 +34,7 @@ class PluginManager(object): self.plugins = {} # module name -> plugin object self.commands = {} # module name -> dict of commands loaded for the module self.event_handlers = {} # module name -> list of event_name/handler pairs loaded for the module + self.poezio_event_handlers = {} def load(self, name): if name in self.plugins: @@ -60,6 +61,7 @@ class PluginManager(object): self.modules[name] = module self.commands[name] = {} self.event_handlers[name] = [] + self.poezio_event_handlers[name] = [] self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir) def unload(self, name): @@ -69,14 +71,14 @@ class PluginManager(object): del self.core.commands[command] for event_name, handler in self.event_handlers[name]: self.core.xmpp.del_event_handler(event_name, handler) - for event_name in self.core.internal_events: - if name in event_name: - del event_name[name] + for handler in self.poezio_event_handlers[name]: + self.core.events.del_event_handler(None, handler) self.plugins[name].unload() del self.plugins[name] del self.commands[name] del self.event_handlers[name] + del self.poezio_event_handlers[name] except Exception as e: import traceback self.core.information(_("Could not unload plugin (may not be safe to try again): ") + traceback.format_exc()) @@ -105,6 +107,16 @@ class PluginManager(object): eh = self.event_handlers[module_name] eh = list(filter(lambda e : e != (event_name, handler), eh)) + def add_poezio_event_handler(self, module_name, event_name, handler, first, last, position): + eh = self.poezio_event_handlers[module_name] + eh.append(handler) + self.core.events.add_event_handler(event_name, handler, first, last, position) + + def del_poezio_event_handler(self, module_name, event_name, handler): + self.core.events.del_event_handler(None, handler) + eh = self.poezio_event_handlers[module_name] + eh = list(filter(lambda e : e != handler, eh)) + def completion_load(self, the_input): """ completion function that completes the name of the plugins, from diff --git a/src/tabs.py b/src/tabs.py index 7e6c5dd2..79be7d58 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -323,7 +323,6 @@ class ChatTab(Tab): if not self.execute_command(clean_text): if txt.startswith('//'): txt = txt[1:] - self.core.run_event('enter', line=txt) self.command_say(txt) self.cancel_paused_delay() @@ -723,6 +722,7 @@ class MucTab(ChatTab): msg['xhtml_im'] = xhtml.poezio_colors_to_html(line) if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: msg['chat_state'] = needed + self.core.events.trigger('muc_say', msg) self.cancel_paused_delay() msg.send() self.chat_state = needed @@ -1216,6 +1216,7 @@ class PrivateTab(ChatTab): if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed + self.core.events.trigger('private_say', msg) msg.send() self.core.add_message_to_text_buffer(self._text_buffer, line, None, self.core.own_nick or self.own_nick) self.cancel_paused_delay() @@ -1879,6 +1880,7 @@ class ConversationTab(ChatTab): if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed + self.core.events.trigger('conversation_say', msg) msg.send() self.core.add_message_to_text_buffer(self._text_buffer, line, None, self.core.own_nick) logger.log_message(JID(self.get_name()).bare, self.core.own_nick, line)