from gettext import gettext as _ import logging log = logging.getLogger(__name__) import curses from . import Tab import windows from common import safeJID from decorators import refresh_wrapper class MucListTab(Tab): """ A tab listing rooms from a specific server, displaying various information, scrollable, and letting the user join them, etc """ plugin_commands = {} plugin_keys = {} def __init__(self, server): Tab.__init__(self) self.state = 'normal' self.name = server columns = ('node-part', 'name', 'users') self.list_header = windows.ColumnHeaderWin(columns) self.listview = windows.ListWin(columns) self.info_header = windows.MucListInfoWin(_('Chatroom list on server %s (Loading)') % self.name) self.default_help_message = windows.HelpText("ā€œjā€: join room.") self.input = self.default_help_message self.key_func["KEY_DOWN"] = self.move_cursor_down self.key_func["KEY_UP"] = self.move_cursor_up self.key_func['^I'] = self.completion self.key_func["/"] = self.on_slash self.key_func['j'] = self.join_selected self.key_func['J'] = self.join_selected_no_focus self.key_func['^M'] = self.join_selected self.key_func['KEY_LEFT'] = self.list_header.sel_column_left self.key_func['KEY_RIGHT'] = self.list_header.sel_column_right self.key_func[' '] = self.sort_by self.register_command('close', self.close, shortdesc=_('Close this tab.')) self.resize() self.update_keys() self.update_commands() def refresh(self): if self.need_resize: self.resize() log.debug(' TAB Refresh: %s',self.__class__.__name__) self.info_header.refresh() self.info_win.refresh() self.refresh_tab_win() self.list_header.refresh() self.listview.refresh() self.input.refresh() self.update_commands() def resize(self): if self.core.information_win_size >= self.height-3 or not self.visible: return self.need_resize = False self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0) column_size = {'node-part': int(self.width*2/8) , 'name': int(self.width*5/8), 'users': self.width-int(self.width*2/8)-int(self.width*5/8)} self.list_header.resize_columns(column_size) self.list_header.resize(1, self.width, 0, 0) self.listview.resize_columns(column_size) self.listview.resize(self.height-3-self.core.information_win_size - Tab.tab_win_height(), self.width, 1, 0) self.input.resize(1, self.width, self.height-1, 0) 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 close(self, arg=None): self.input.on_delete() self.core.close_tab(self) def join_selected_no_focus(self): return def set_error(self, msg, code, body): """ If there's an error (retrieving the values etc) """ self._error_message = _('Error: %(code)s - %(msg)s: %(body)s') % {'msg':msg, 'body':body, 'code':code} self.info_header.message = self._error_message self.info_header.refresh() curses.doupdate() def on_muc_list_item_received(self, iq): """ Callback called when a disco#items result is received Used with command_list """ if iq['type'] == 'error': self.set_error(iq['error']['type'], iq['error']['code'], iq['error']['text']) return items = [{'node-part': safeJID(item[0]).user if safeJID(item[0]).server == self.name else safeJID(item[0]).bare, 'jid': item[0], 'name': item[2] or '' ,'users': ''} for item in iq['disco_items'].get_items()] self.listview.add_lines(items) self.info_header.message = _('Chatroom list on server %s') % self.name if self.core.current_tab() is self: self.listview.refresh() self.info_header.refresh() else: self.state = 'highlight' self.refresh_tab_win() curses.doupdate() def sort_by(self): if self.list_header.get_order(): self.listview.sort_by_column(col_name=self.list_header.get_sel_column(),asc=False) self.list_header.set_order(False) self.list_header.refresh() else: self.listview.sort_by_column(col_name=self.list_header.get_sel_column(),asc=True) self.list_header.set_order(True) self.list_header.refresh() curses.doupdate() def join_selected(self): row = self.listview.get_selected_row() if not row: return self.core.command_join(row['jid']) @refresh_wrapper.always def reset_help_message(self, _=None): curses.curs_set(0) self.input = self.default_help_message self.input.resize(1, self.width, self.height-1, 0) return True def execute_slash_command(self, txt): if txt.startswith('/'): self.input.key_enter() self.execute_command(txt) return self.reset_help_message() def get_name(self): return self.name 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 on_info_win_size_changed(self): if self.core.information_win_size >= self.height-3: return self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0) self.listview.resize(self.height-3-self.core.information_win_size - Tab.tab_win_height(), self.width, 1, 0) def on_lose_focus(self): self.state = 'normal' def on_gain_focus(self): self.state = 'current' curses.curs_set(0) def on_scroll_up(self): return self.listview.scroll_up() def on_scroll_down(self): return self.listview.scroll_down() def move_cursor_up(self): self.listview.move_cursor_up() self.listview.refresh() self.core.doupdate() def move_cursor_down(self): self.listview.move_cursor_down() self.listview.refresh() self.core.doupdate() def matching_names(self): return [(2, self.name)]