diff options
author | mathieui <mathieui@mathieui.net> | 2014-03-19 02:22:25 +0100 |
---|---|---|
committer | mathieui <mathieui@mathieui.net> | 2014-03-19 02:22:25 +0100 |
commit | 1c621caae1204ec9a59b38a326c13bfe04be168c (patch) | |
tree | e69dc839d0fcfa39a8704e1fdbf3d7ca7df3cb26 /src/tabs/xmltab.py | |
parent | be74128cb78ebd9c8316816f04632acd12396579 (diff) | |
download | poezio-1c621caae1204ec9a59b38a326c13bfe04be168c.tar.gz poezio-1c621caae1204ec9a59b38a326c13bfe04be168c.tar.bz2 poezio-1c621caae1204ec9a59b38a326c13bfe04be168c.tar.xz poezio-1c621caae1204ec9a59b38a326c13bfe04be168c.zip |
split the "tabs" module into separate files
- todo: write a common import file to avoid duplicating the imports
Diffstat (limited to 'src/tabs/xmltab.py')
-rw-r--r-- | src/tabs/xmltab.py | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/src/tabs/xmltab.py b/src/tabs/xmltab.py new file mode 100644 index 00000000..ed099405 --- /dev/null +++ b/src/tabs/xmltab.py @@ -0,0 +1,195 @@ +from gettext import gettext as _ + +import logging +log = logging.getLogger(__name__) + +import curses +from sleekxmpp.xmlstream import matcher +from sleekxmpp.xmlstream.handler import Callback + +from . import Tab + +import windows + +class XMLTab(Tab): + def __init__(self): + Tab.__init__(self) + self.state = 'normal' + self.text_win = windows.TextWin() + self.core.xml_buffer.add_window(self.text_win) + self.info_header = windows.XMLInfoWin() + self.default_help_message = windows.HelpText("/ to enter a command") + self.register_command('close', self.close, + shortdesc=_("Close this tab.")) + self.register_command('clear', self.command_clear, + shortdesc=_('Clear the current buffer.')) + self.register_command('reset', self.command_reset, + shortdesc=_('Reset the stanza filter.')) + self.register_command('filter_id', self.command_filter_id, + usage='<id>', + desc=_('Show only the stanzas with the id <id>.'), + shortdesc=_('Filter by id.')) + self.register_command('filter_xpath', self.command_filter_xpath, + usage='<xpath>', + desc=_('Show only the stanzas matching the xpath <xpath>.'), + shortdesc=_('Filter by XPath.')) + self.register_command('filter_xmlmask', self.command_filter_xmlmask, + usage=_('<xml mask>'), + desc=_('Show only the stanzas matching the given xml mask.'), + shortdesc=_('Filter by xml mask.')) + self.input = self.default_help_message + self.key_func['^T'] = self.close + self.key_func['^I'] = self.completion + self.key_func["KEY_DOWN"] = self.on_scroll_down + self.key_func["KEY_UP"] = self.on_scroll_up + self.key_func["^K"] = self.on_freeze + self.key_func["/"] = self.on_slash + self.resize() + # Used to display the infobar + self.filter_type = '' + self.filter = '' + + def on_freeze(self): + """ + Freeze the display. + """ + self.text_win.toggle_lock() + self.refresh() + + def command_filter_xmlmask(self, arg): + """/filter_xmlmask <xml mask>""" + try: + handler = Callback('custom matcher', matcher.MatchXMLMask(arg), + self.core.incoming_stanza) + self.core.xmpp.remove_handler('custom matcher') + self.core.xmpp.register_handler(handler) + self.filter_type = "XML Mask Filter" + self.filter = arg + self.refresh() + except: + self.core.information('Invalid XML Mask', 'Error') + self.command_reset('') + + def command_filter_id(self, arg): + """/filter_id <id>""" + self.core.xmpp.remove_handler('custom matcher') + handler = Callback('custom matcher', matcher.MatcherId(arg), + self.core.incoming_stanza) + self.core.xmpp.register_handler(handler) + self.filter_type = "Id Filter" + self.filter = arg + self.refresh() + + def command_filter_xpath(self, arg): + """/filter_xpath <xpath>""" + try: + handler = Callback('custom matcher', matcher.MatchXPath( + arg.replace('%n', self.core.xmpp.default_ns)), + self.core.incoming_stanza) + self.core.xmpp.remove_handler('custom matcher') + self.core.xmpp.register_handler(handler) + self.filter_type = "XPath Filter" + self.filter = arg + self.refresh() + except: + self.core.information('Invalid XML Path', 'Error') + self.command_reset('') + + def command_reset(self, arg): + """/reset""" + self.core.xmpp.remove_handler('custom matcher') + self.core.xmpp.register_handler(self.core.all_stanzas) + self.filter_type = '' + self.filter = '' + self.refresh() + + def on_slash(self): + """ + '/' is pressed, activate the input + """ + curses.curs_set(1) + self.input = windows.CommandInput("", self.reset_help_message, self.execute_slash_command) + self.input.resize(1, self.width, self.height-1, 0) + self.input.do_command("/") # we add the slash + + def reset_help_message(self, _=None): + if self.core.current_tab() is self: + curses.curs_set(0) + self.input = self.default_help_message + self.input.refresh() + self.core.doupdate() + return True + + def on_scroll_up(self): + return self.text_win.scroll_up(self.text_win.height-1) + + def on_scroll_down(self): + return self.text_win.scroll_down(self.text_win.height-1) + + def command_clear(self, args): + """ + /clear + """ + self.core.xml_buffer.messages = [] + self.text_win.rebuild_everything(self.core.xml_buffer) + self.refresh() + self.core.doupdate() + + def execute_slash_command(self, txt): + if txt.startswith('/'): + self.input.key_enter() + self.execute_command(txt) + return self.reset_help_message() + + def completion(self): + if isinstance(self.input, windows.Input): + self.complete_commands(self.input) + + def on_input(self, key, raw): + res = self.input.do_command(key, raw=raw) + if res: + return True + if not raw and key in self.key_func: + return self.key_func[key]() + + def close(self, arg=None): + self.core.close_tab() + + def resize(self): + if self.core.information_win_size >= self.height-3 or not self.visible: + return + self.need_resize = False + min = 1 if self.left_tab_win else 2 + self.text_win.resize(self.height-self.core.information_win_size - Tab.tab_win_height() - 2, self.width, 0, 0) + self.text_win.rebuild_everything(self.core.xml_buffer) + self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0) + self.input.resize(1, self.width, self.height-1, 0) + + def refresh(self): + if self.need_resize: + self.resize() + log.debug(' TAB Refresh: %s',self.__class__.__name__) + self.text_win.refresh() + self.info_header.refresh(self.filter_type, self.filter, self.text_win) + self.refresh_tab_win() + self.info_win.refresh() + self.input.refresh() + + def on_lose_focus(self): + self.state = 'normal' + + def on_gain_focus(self): + self.state = 'current' + curses.curs_set(0) + + def on_close(self): + self.command_clear('') + self.core.xml_tab = False + + def on_info_win_size_changed(self): + if self.core.information_win_size >= self.height-3: + return + self.text_win.resize(self.height-2-self.core.information_win_size - Tab.tab_win_height(), self.width, 0, 0) + self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0) + + |