def command_info(self): contact = roster[self.get_dest_jid()] jid = safeJID(self.get_dest_jid()) if contact: if jid.resource: resource = contact[jid.full] else: resource = contact.get_highest_priority_resource() else: resource = None if resource: status = (_('Status: %s') % resource.status) if resource.status else '' self._text_buffer.add_message( "\x19%(info_col)s}Show: %(show)s, %(status)s\x19o" % { 'show': resource.show or 'available', 'status': status, 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT) }) return True else: self._text_buffer.add_message( "\x19%(info_col)s}No information available\x19o" % {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)}) return True
def build_message(self, message, timestamp=False): txt = message.txt ret = [] default_color = None nick = truncate_nick(message.nickname) offset = 0 if nick: offset += poopt.wcswidth(nick) + 1 # + nick + ' ' length if message.str_time: offset += 1 + len(message.str_time) if get_theme().CHAR_TIME_LEFT and message.str_time: offset += 1 if get_theme().CHAR_TIME_RIGHT and message.str_time: offset += 1 lines = poopt.cut_text(txt, self.width - offset - 1) prepend = default_color if default_color else '' attrs = [] for line in lines: saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend) attrs = parse_attrs(message.txt[line[0]:line[1]], attrs) if attrs: prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs) else: if default_color: prepend = default_color else: prepend = '' ret.append(saved) return ret
def go_to_previous_input(self): if not self.inputs: return if self.current_input == 0: return self.inputs[self.current_input]['input'].set_color( get_theme().COLOR_NORMAL_TEXT) self.inputs[self.current_input]['label'].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_input -= 1 jump = 0 while self.current_input - jump > 0 and self.inputs[ self.current_input + jump]['input'].is_dummy(): jump += 1 if self.inputs[self.current_input + jump]['input'].is_dummy(): return # Adjust the scroll position if the current_input would be outside # of the visible area if self.current_input < self.scroll_pos: self.scroll_pos = self.current_input self.refresh() self.current_input -= jump self.inputs[self.current_input]['input'].set_color( get_theme().COLOR_SELECTED_ROW) self.inputs[self.current_input]['label'].set_color( get_theme().COLOR_SELECTED_ROW)
def go_to_next_input(self): if not self.inputs: return if self.current_input == len(self.inputs) - 1: return self.inputs[self.current_input]['input'].set_color( get_theme().COLOR_NORMAL_TEXT) self.inputs[self.current_input]['label'].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_input += 1 jump = 0 while self.current_input + jump != len( self.inputs) - 1 and self.inputs[self.current_input + jump]['input'].is_dummy(): jump += 1 if self.inputs[self.current_input + jump]['input'].is_dummy(): return self.current_input += jump # If moving made the current input out of the visible screen, we # adjust the scroll position and we redraw the whole thing. We don’t # call refresh() if this is not the case, because # refresh_current_input() is always called anyway, so this is not # needed if self.current_input - self.scroll_pos > self.height - 1: self.scroll_pos += 1 self.refresh() self.inputs[self.current_input]['input'].set_color( get_theme().COLOR_SELECTED_ROW) self.inputs[self.current_input]['label'].set_color( get_theme().COLOR_SELECTED_ROW)
def refresh(self): self._win.erase() y = -self.scroll_pos i = 0 for name, field in self._form.getFields().items(): if field['type'] == 'hidden': continue self.inputs[i]['label'].resize(1, self.width//2, y + 1, 0) self.inputs[i]['input'].resize(1, self.width//2, y+1, self.width//2) # TODO: display the field description y += 1 i += 1 self._win.refresh() for i, inp in enumerate(self.inputs): if i < self.scroll_pos: continue if i >= self.height + self.scroll_pos: break inp['label'].refresh() inp['input'].refresh() inp['label'].refresh() if self.current_input < self.height-1: self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW) self.inputs[self.current_input]['input'].refresh() self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW) self.inputs[self.current_input]['label'].refresh()
def write_nack(self): color = get_theme().COLOR_CHAR_NACK self._win.attron(to_curses_attr(color)) self.addstr(get_theme().CHAR_NACK) self._win.attroff(to_curses_attr(color)) self.addstr(' ') return poopt.wcswidth(get_theme().CHAR_NACK) + 1
def on_groupchat_subject(self, message): """ Triggered when the topic is changed. """ nick_from = message['mucnick'] room_from = message.get_mucroom() tab = self.get_tab_by_name(room_from, tabs.MucTab) subject = message['subject'] if subject is None or not tab: return if subject != tab.topic: # Do not display the message if the subject did not change or if we # receive an empty topic when joining the room. if nick_from: tab.add_message(_("\x19%(info_col)s}%(nick)s set the subject to: %(subject)s") % {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT), 'nick':nick_from, 'subject':subject}, time=None, typ=2) else: tab.add_message(_("\x19%(info_col)s}The subject is: %(subject)s") % {'subject':subject, 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)}, time=None, typ=2) tab.topic = subject tab.topic_from = nick_from if self.get_tab_by_name(room_from, tabs.MucTab) is self.current_tab(): self.refresh_window()
def callback(iq): if iq['type'] != 'result': if iq['error']['type'] == 'auth': self.core.information( 'You are not allowed to see the activity of this contact.', 'Error') else: self.core.information('Error retrieving the activity', 'Error') return seconds = iq['last_activity']['seconds'] status = iq['last_activity']['status'] from_ = iq['from'] msg = '\x19%s}The last activity of %s was %s ago%s' if not safeJID(from_).user: msg = '\x19%s}The uptime of %s is %s.' % ( dump_tuple(get_theme().COLOR_INFORMATION_TEXT), from_, common.parse_secs_to_str(seconds)) else: msg = '\x19%s}The last activity of %s was %s ago%s' % ( dump_tuple(get_theme().COLOR_INFORMATION_TEXT), from_, common.parse_secs_to_str(seconds), (' and his/her last status was %s' % status) if status else '', ) self.add_message(msg) self.core.refresh_window()
def user_left(self, status_message, from_nick): """ The user left the associated MUC """ self.deactivate() if not status_message: self.add_message( '\x191}%(spec)s \x193}%(nick)s\x19%(info_col)s} has left the room' % { 'nick': from_nick, 'spec': get_theme().CHAR_QUIT, 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT) }, typ=2) else: self.add_message( '\x191}%(spec)s \x193}%(nick)s\x19%(info_col)s} has left the room (%(status)s)"' % { 'nick': from_nick, 'spec': get_theme().CHAR_QUIT, 'status': status_message, 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT) }, typ=2) return self.core.current_tab() is self
def draw_group_info(self, group): """ draw the group information """ self.addstr(0, 0, group.name, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR)
def write_contact_jid(self, jid): """ Just write the jid that we are talking to """ self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.addstr(jid.full, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def features_checked(self, iq): "Features check callback" features = iq['disco_info'].get_features() or [] before = ('correct' in self.commands, self.remote_supports_attention, self.remote_supports_receipts) correct = self._feature_correct(features) attention = self._feature_attention(features) receipts = self._feature_receipts(features) if (correct, attention, receipts) == before and self.__initial_disco: return else: self.__initial_disco = True if not (correct or attention or receipts): return # don’t display anything ok = get_theme().CHAR_OK nope = get_theme().CHAR_EMPTY correct = ok if correct else nope attention = ok if attention else nope receipts = ok if receipts else nope msg = ('\x19%s}Contact supports: correction [%s], ' 'attention [%s], receipts [%s].') color = dump_tuple(get_theme().COLOR_INFORMATION_TEXT) msg = msg % (color, correct, attention, receipts) self.add_message(msg, typ=0) self.core.refresh_window()
def build_message(self, message, timestamp=False): txt = message.txt ret = [] default_color = None nick = truncate_nick(message.nickname) offset = 0 if nick: offset += poopt.wcswidth(nick) + 1 # + nick + ' ' length if message.str_time: offset += 1 + len(message.str_time) if get_theme().CHAR_TIME_LEFT and message.str_time: offset += 1 if get_theme().CHAR_TIME_RIGHT and message.str_time: offset += 1 lines = poopt.cut_text(txt, self.width-offset-1) prepend = default_color if default_color else '' attrs = [] for line in lines: saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend) attrs = parse_attrs(message.txt[line[0]:line[1]], attrs) if attrs: prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs) else: if default_color: prepend = default_color else: prepend = '' ret.append(saved) return ret
def features_checked(self, iq): "Features check callback" features = iq['disco_info'].get_features() or [] before = ('correct' in self.commands, self.remote_supports_attention, self.remote_supports_receipts) correct = self._feature_correct(features) attention = self._feature_attention(features) receipts = self._feature_receipts(features) if (correct, attention, receipts) == before and self.__initial_disco: return else: self.__initial_disco = True if not (correct or attention or receipts): return # don’t display anything ok = get_theme().CHAR_OK nope = get_theme().CHAR_EMPTY correct = ok if correct else nope attention = ok if attention else nope receipts = ok if receipts else nope msg = _('\x19%s}Contact supports: correction [%s], ' 'attention [%s], receipts [%s].') color = dump_tuple(get_theme().COLOR_INFORMATION_TEXT) msg = msg % (color, correct, attention, receipts) self.add_message(msg, typ=0) self.core.refresh_window()
def go_to_next_horizontal_input(self): if not self.lines: return self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input += 1 if self.current_horizontal_input > 3: self.current_horizontal_input = 0 self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
def go_to_previous_horizontal_input(self): if not self.lines: return if self.current_horizontal_input == 0: return self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input -= 1 self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
def refresh(self, txt=None): log.debug('Refresh: %s', self.__class__.__name__) if txt: self.txt = txt self._win.erase() self.addstr(0, 0, self.txt[:self.width-1], to_curses_attr(get_theme().COLOR_WARNING_PROMPT)) self.finish_line(get_theme().COLOR_WARNING_PROMPT) self._refresh()
def refresh(self, txt=None): log.debug('Refresh: %s', self.__class__.__name__) if txt: self.txt = txt self._win.erase() self.addstr(0, 0, self.txt[:self.width - 1], to_curses_attr(get_theme().COLOR_WARNING_PROMPT)) self.finish_line(get_theme().COLOR_WARNING_PROMPT) self._refresh()
def draw_roster_information(self, roster): """ The header at the top """ self.addstr( 'Roster: %s/%s contacts' % (roster.get_nb_connected_contacts(), len(roster)), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR)
def draw_roster_information(self, roster): """ The header at the top """ self.addstr('Roster: %s/%s contacts' % ( roster.get_nb_connected_contacts(), len(roster)), to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR)
def write_contact_informations(self, contact): """ Write the informations about the contact """ if not contact: self.addstr("(contact not in roster)", to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) return display_name = contact.name if display_name: self.addstr('%s '%(display_name), to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def draw_status_chatstate(self, y, user): show_col = get_theme().color_show(user.show) if user.chatstate == 'composing': char = get_theme().CHAR_CHATSTATE_COMPOSING elif user.chatstate == 'active': char = get_theme().CHAR_CHATSTATE_ACTIVE elif user.chatstate == 'paused': char = get_theme().CHAR_CHATSTATE_PAUSED else: char = get_theme().CHAR_STATUS self.addstr(y, 0, char, to_curses_attr(show_col))
def write_contact_jid(self, jid): """ Just displays the resource in an other color """ log.debug("write_contact_jid DynamicConversationInfoWin, jid: %s", jid.resource) self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.addstr(jid.bare, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) if jid.resource: self.addstr("/%s" % (jid.resource,), to_curses_attr(get_theme().COLOR_CONVERSATION_RESOURCE)) self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def build_message(self, message, timestamp=False, nick_size=10): """ Build a list of lines from a message, without adding it to a list """ if message is None: # line separator return [None] txt = message.txt if not txt: return [] if len(message.str_time) > 8: default_color = (FORMAT_CHAR + dump_tuple(get_theme().COLOR_LOG_MSG) + '}') else: default_color = None ret = [] nick = truncate_nick(message.nickname, nick_size) offset = 0 if message.ack: if message.ack > 0: offset += poopt.wcswidth(get_theme().CHAR_ACK_RECEIVED) + 1 else: offset += poopt.wcswidth(get_theme().CHAR_NACK) + 1 if nick: offset += poopt.wcswidth(nick) + 2 # + nick + '> ' length if message.revisions > 0: offset += ceil(log10(message.revisions + 1)) if message.me: offset += 1 # '* ' before and ' ' after if timestamp: if message.str_time: offset += 1 + len(message.str_time) if get_theme().CHAR_TIME_LEFT and message.str_time: offset += 1 if get_theme().CHAR_TIME_RIGHT and message.str_time: offset += 1 lines = poopt.cut_text(txt, self.width - offset - 1) prepend = default_color if default_color else '' attrs = [] for line in lines: saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend) attrs = parse_attrs(message.txt[line[0]:line[1]], attrs) if attrs: prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs) else: if default_color: prepend = default_color else: prepend = '' ret.append(saved) return ret
def refresh(self, name=None, window=None): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() if name: self.addstr(name, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) else: self.addstr(self.message, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) if window: self.print_scroll_position(window) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh()
def draw_resource_line(self, y, resource, colored): """ Draw a specific resource line """ color = get_theme().color_show(resource.presence) self.addstr(y, 4, get_theme().CHAR_STATUS, to_curses_attr(color)) if colored: self.addstr(y, 6, self.truncate_name(str(resource.jid), 6), to_curses_attr(get_theme().COLOR_SELECTED_ROW)) else: self.addstr(y, 6, self.truncate_name(str(resource.jid), 6)) self.finish_line()
def go_to_next_horizontal_input(self): if not self.lines: return self.lines[self.current_input][ self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input += 1 if self.current_horizontal_input > 3: self.current_horizontal_input = 0 self.lines[self.current_input][ self.current_horizontal_input].set_color( get_theme().COLOR_SELECTED_ROW)
def write_resource_information(self, resource): """ Write the informations about the resource """ if not resource: presence = "unavailable" else: presence = resource.presence color = get_theme().color_show(presence) self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.addstr(get_theme().CHAR_STATUS, to_curses_attr(color)) self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def go_to_previous_horizontal_input(self): if not self.lines: return if self.current_horizontal_input == 0: return self.lines[self.current_input][ self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input -= 1 self.lines[self.current_input][ self.current_horizontal_input].set_color( get_theme().COLOR_SELECTED_ROW)
def refresh(self, filter_t='', filter='', window=None): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() bar = to_curses_attr(get_theme().COLOR_INFORMATION_BAR) if not filter_t: self.addstr('[No filter]', bar) else: info = '[%s] %s' % (filter_t, filter) self.addstr(info, bar) self.print_scroll_position(window) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh()
def write_contact_informations(self, contact): """ Write the informations about the contact """ if not contact: self.addstr("(contact not in roster)", to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) return display_name = contact.name if display_name: self.addstr('%s ' % (display_name), to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def command_smp(self, args): """ /otrsmp <ask|answer|abort> [question] [secret] """ if args is None or not args: return self.core.command_help('otrsmp') length = len(args) action = args.pop(0) if length == 2: question = None secret = args.pop(0).encode('utf-8') elif length == 3: question = args.pop(0).encode('utf-8') secret = args.pop(0).encode('utf-8') else: question = secret = None tab = self.api.current_tab() name = tab.name if isinstance(tab, DynamicConversationTab) and tab.locked_resource: name = safeJID(tab.name) name.resource = tab.locked_resource name = name.full format_dict = { 'jid_c': '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID), 'info': '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT), 'jid': name, 'bare_jid': safeJID(name).bare } ctx = self.get_context(name) if ctx.state != STATE_ENCRYPTED: self.api.information('The current conversation is not encrypted', 'Error') return if action == 'ask': ctx.in_smp = True ctx.smp_own = True if question: ctx.smpInit(secret, question) else: ctx.smpInit(secret) tab.add_message(SMP_INITIATED % format_dict, typ=0) elif action == 'answer': ctx.smpGotSecret(secret) elif action == 'abort': if ctx.in_smp: ctx.smpAbort() tab.add_message(SMP_ABORTED % format_dict, typ=0) self.core.refresh_window()
def go_to_previous_line_input(self): if not self.lines: return if self.current_input == 0: return self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) self.current_input -= 1 # Adjust the scroll position if the current_input would be outside # of the visible area if self.current_input < self.scroll_pos: self.scroll_pos = self.current_input self.refresh() self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
def build_message(self, message, timestamp=False): """ Build a list of lines from a message, without adding it to a list """ if message is None: # line separator return [None] txt = message.txt if not txt: return [] if len(message.str_time) > 8: default_color = (FORMAT_CHAR + dump_tuple(get_theme().COLOR_LOG_MSG) + '}') else: default_color = None ret = [] nick = truncate_nick(message.nickname) offset = 0 if message.ack: if message.ack > 0: offset += poopt.wcswidth(get_theme().CHAR_ACK_RECEIVED) + 1 else: offset += poopt.wcswidth(get_theme().CHAR_NACK) + 1 if nick: offset += poopt.wcswidth(nick) + 2 # + nick + '> ' length if message.revisions > 0: offset += ceil(log10(message.revisions + 1)) if message.me: offset += 1 # '* ' before and ' ' after if timestamp: if message.str_time: offset += 1 + len(message.str_time) if get_theme().CHAR_TIME_LEFT and message.str_time: offset += 1 if get_theme().CHAR_TIME_RIGHT and message.str_time: offset += 1 lines = poopt.cut_text(txt, self.width-offset-1) prepend = default_color if default_color else '' attrs = [] for line in lines: saved = Line(msg=message, start_pos=line[0], end_pos=line[1], prepend=prepend) attrs = parse_attrs(message.txt[line[0]:line[1]], attrs) if attrs: prepend = FORMAT_CHAR + FORMAT_CHAR.join(attrs) else: if default_color: prepend = default_color else: prepend = '' ret.append(saved) return ret
def make_message(txt, time, nickname, nick_color, history, user, identifier, str_time=None, highlight=False, old_message=None, revisions=0, jid=None, ack=None): """ Create a new Message object with parameters, check for /me messages, and delayed messages """ time = time or datetime.now() if txt.startswith('/me '): me = True txt = '\x19%s}%s' % (dump_tuple( get_theme().COLOR_ME_MESSAGE), txt[4:]) else: me = False if history: txt = txt.replace( '\x19o', '\x19o\x19%s}' % dump_tuple(get_theme().COLOR_LOG_MSG)) str_time = time.strftime("%Y-%m-%d %H:%M:%S") else: if str_time is None: str_time = time.strftime("%H:%M:%S") else: str_time = '' msg = Message(txt='%s\x19o' % (txt.replace('\t', ' '), ), nick_color=nick_color, time=time, str_time=str_time, nickname=nickname, user=user, identifier=identifier, highlight=highlight, me=me, old_message=old_message, revisions=revisions, jid=jid, ack=ack) log.debug('Set message %s with %s.', identifier, msg) return msg
def write_contact_jid(self, jid): """ Just displays the resource in an other color """ log.debug("write_contact_jid DynamicConversationInfoWin, jid: %s", jid.resource) self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.addstr(jid.bare, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) if jid.resource: self.addstr( "/%s" % (jid.resource, ), to_curses_attr(get_theme().COLOR_CONVERSATION_RESOURCE)) self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def refresh(self, topic=None): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() if topic: msg = topic[:self.width-1] else: msg = self._message[:self.width-1] self.addstr(0, 0, msg, to_curses_attr(get_theme().COLOR_TOPIC_BAR)) (y, x) = self._win.getyx() remaining_size = self.width - x if remaining_size: self.addnstr(' '*remaining_size, remaining_size, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self._refresh()
def refresh(self, topic=None): log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() if topic: msg = topic[:self.width - 1] else: msg = self._message[:self.width - 1] self.addstr(0, 0, msg, to_curses_attr(get_theme().COLOR_TOPIC_BAR)) (y, x) = self._win.getyx() remaining_size = self.width - x if remaining_size: self.addnstr(' ' * remaining_size, remaining_size, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self._refresh()
def on_conversation_say(self, msg, tab): """ On message sent """ if isinstance(tab, DynamicConversationTab) and tab.locked_resource: jid = safeJID(tab.name) jid.resource = tab.locked_resource name = jid.full else: name = tab.name jid = safeJID(tab.name) format_dict = { 'jid_c': '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID), 'info': '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT), 'jid': name, } ctx = None default_ctx = self.get_context(name) if isinstance(tab, DynamicConversationTab) and not tab.locked_resource: log.debug('Unlocked tab %s found, falling back to the first encrypted chat we find.', name) ctx = self.find_encrypted_context_with_matching(jid.bare) if ctx is None: ctx = default_ctx if ctx and ctx.state == STATE_ENCRYPTED: ctx.sendMessage(0, msg['body'].encode('utf-8')) if not tab.send_chat_state('active'): tab.send_chat_state('inactive', always_send=True) tab.add_message(msg['body'], nickname=self.core.own_nick or tab.own_nick, nick_color=get_theme().COLOR_OWN_NICK, identifier=msg['id'], jid=self.core.xmpp.boundjid, typ=ctx.log) # remove everything from the message so that it doesn’t get sent del msg['body'] del msg['replace'] del msg['html'] elif ctx and ctx.getPolicy('REQUIRE_ENCRYPTION'): tab.add_message(MESSAGE_NOT_SENT % format_dict, typ=0) del msg['body'] del msg['replace'] del msg['html'] self.otr_start(tab, name, format_dict)
def go_to_next_line_input(self): if not self.lines: return if self.current_input == len(self.lines) - 1: return self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_NORMAL_TEXT) # Adjust the scroll position if the current_input would be outside # of the visible area if self.current_input + 1 - self.scroll_pos > self.height-1: self.current_input += 1 self.scroll_pos += 1 self.refresh() else: self.current_input += 1 self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW)
def draw_group(self, y, group, colored): """ Draw a groupname on a line """ if colored: self._win.attron(to_curses_attr(get_theme().COLOR_SELECTED_ROW)) if group.folded: self.addstr(y, 0, '[+] ') else: self.addstr(y, 0, '[-] ') contacts = " (%s/%s)" % (group.get_nb_connected_contacts(), len(group)) self.addstr(y, 4, self.truncate_name(group.name, len(contacts)+4) + contacts) if colored: self._win.attroff(to_curses_attr(get_theme().COLOR_SELECTED_ROW)) self.finish_line()
def refresh(self, jid, contact, window, chatstate, informations): # contact can be None, if we receive a message # from someone not in our roster. In this case, we display # only the maximum information from the message we can get. log.debug('Refresh: %s', self.__class__.__name__) jid = safeJID(jid) if contact: if jid.resource: resource = contact[jid.full] else: resource = contact.get_highest_priority_resource() else: resource = None # if contact is None, then resource is None too: # user is not in the roster so we know almost nothing about it # If contact is a Contact, then # resource can now be a Resource: user is in the roster and online # or resource is None: user is in the roster but offline self._win.erase() self.write_contact_jid(jid) self.write_contact_informations(contact) self.write_resource_information(resource) self.print_scroll_position(window) self.write_chatstate(chatstate) self.write_additional_informations(informations, jid) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh()
def write_disconnected(self, room): """ Shows a message if the room is not joined """ if not room.joined: self.addstr(' -!- Not connected ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def write_additional_informations(self, informations, jid): """ Write all informations added by plugins by getting the value returned by the callbacks. """ for key in informations: self.addstr(informations[key](jid), to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
def refresh(self): # store the cursor status self._win.erase() y = - self.scroll_pos for i in range(len(self.lines)): self.lines[i][0].resize(1, self.width//3, y + 1, 0) self.lines[i][1].resize(1, self.width//3, y + 1, self.width//3) self.lines[i][2].resize(1, self.width//6, y + 1, 2*self.width//3) self.lines[i][3].resize(1, self.width//6, y + 1, 5*self.width//6) y += 1 self._refresh() for i, inp in enumerate(self.lines): if i < self.scroll_pos: continue if i >= self.height + self.scroll_pos: break for j in range(4): inp[j].refresh() if self.lines and self.current_input < self.height-1: self.lines[self.current_input][self.current_horizontal_input].set_color(get_theme().COLOR_SELECTED_ROW) self.lines[self.current_input][self.current_horizontal_input].refresh() if not self.lines: curses.curs_set(0) else: curses.curs_set(1)
def refresh(self, jid, contact, window, chatstate, informations): # contact can be None, if we receive a message # from someone not in our roster. In this case, we display # only the maximum information from the message we can get. log.debug('Refresh: %s', self.__class__.__name__) jid = safeJID(jid) if contact: if jid.resource: resource = contact[jid.full] else: resource = contact.get_highest_priority_resource() else: resource = None # if contact is None, then resource is None too: # user is not in the roster so we know almost nothing about it # If contact is a Contact, then # resource can now be a Resource: user is in the roster and online # or resource is None: user is in the roster but offline self._win.erase() if config.get('show_jid_in_conversations'): self.write_contact_jid(jid) self.write_contact_informations(contact) self.write_resource_information(resource) self.print_scroll_position(window) self.write_chatstate(chatstate) self.write_additional_informations(informations, jid) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh()
def remote_wants_chatstates(self, value): old_value = self._remote_wants_chatstates self._remote_wants_chatstates = value if (old_value is None and value != None) or \ (old_value != value and value != None): ok = get_theme().CHAR_OK nope = get_theme().CHAR_EMPTY support = ok if value else nope if value: msg = _('\x19%s}Contact supports chat states [%s].') else: msg = _('\x19%s}Contact does not support chat states [%s].') color = dump_tuple(get_theme().COLOR_INFORMATION_TEXT) msg = msg % (color, support) self.add_message(msg, typ=0) self.core.refresh_window()
def on_conversation_say(self, msg, tab): """ On message sent """ if isinstance(tab, DynamicConversationTab) and tab.locked_resource: jid = safeJID(tab.name) jid.resource = tab.locked_resource name = jid.full else: name = tab.name jid = safeJID(tab.name) ctx = self.contexts.get(name) if isinstance(tab, DynamicConversationTab) and not tab.locked_resource: log.debug('Unlocked tab %s found, falling back to the first encrypted chat we find.', name) ctx = self.find_encrypted_context_with_matching(jid.bare) if ctx and ctx.state == STATE_ENCRYPTED: ctx.sendMessage(0, msg['body'].encode('utf-8')) if not tab.send_chat_state('active'): tab.send_chat_state('inactive', always_send=True) tab.add_message(msg['body'], nickname=self.core.own_nick or tab.own_nick, nick_color=get_theme().COLOR_OWN_NICK, identifier=msg['id'], jid=self.core.xmpp.boundjid, typ=ctx.log) # remove everything from the message so that it doesn’t get sent del msg['body'] del msg['replace'] del msg['html']
def __init__(self, field): FieldInput.__init__(self, field) Input.__init__(self) self.text = field.getValue() if isinstance(field.getValue(), str)\ else "" self.pos = len(self.text) self.color = get_theme().COLOR_NORMAL_TEXT