From 91fde24388c97d5f74b1b68d5ada7f69725ab964 Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 13 Apr 2015 17:32:35 +0200 Subject: Display error messages inside a conversation if the error has the same id as a sent message, it will be displayed with a cross where there is usually a checkmark (ack), and the received error will be appended to the message, in red. if it does not have a know id, it will be added as another message to the conversation, without a nick, and in red. --- src/core/handlers.py | 11 ++++++++++- src/tabs/basetabs.py | 11 +++++++++++ src/text_buffer.py | 20 ++++++++++++++++---- src/theming.py | 2 ++ src/windows/text_win.py | 24 ++++++++++++++++++++---- 5 files changed, 59 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/core/handlers.py b/src/core/handlers.py index a28e7410..3a5e9ea1 100644 --- a/src/core/handlers.py +++ b/src/core/handlers.py @@ -237,7 +237,16 @@ def on_error_message(self, message): return self.room_error(message, jid_from) else: return self.on_groupchat_private_message(message) - return self.information(self.get_error_message(message, deprecated=True), 'Error') + tab = self.get_conversation_by_jid(message['from'], create=False) + error_msg = self.get_error_message(message, deprecated=True) + if not tab: + return self.information(error_msg, _('Error')) + error = '\x19%s}%s\x19o' % (dump_tuple(get_theme().COLOR_CHAR_NACK), + error_msg) + if not tab.nack_message('\n' + error, message['id'], message['to']): + tab.add_message(error, typ=0) + self.refresh_window() + def on_normal_message(self, message): """ diff --git a/src/tabs/basetabs.py b/src/tabs/basetabs.py index 16752b5e..184a9243 100644 --- a/src/tabs/basetabs.py +++ b/src/tabs/basetabs.py @@ -747,6 +747,17 @@ class OneToOneTab(ChatTab): self.text_win.modify_message(msg_id, new_msg) self.core.refresh_window() + def nack_message(self, error, msg_id, msg_jid): + """ + Ack a message + """ + new_msg = self._text_buffer.nack_message(error, msg_id, msg_jid) + if new_msg: + self.text_win.modify_message(msg_id, new_msg) + self.core.refresh_window() + return True + return False + @command_args_parser.raw def command_xhtml(self, xhtml_data): message = self.generate_xhtml_message(xhtml_data) diff --git a/src/text_buffer.py b/src/text_buffer.py index db68c11f..14936072 100644 --- a/src/text_buffer.py +++ b/src/text_buffer.py @@ -87,7 +87,7 @@ class TextBuffer(object): @staticmethod 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): + old_message=None, revisions=0, jid=None, ack=0): """ Create a new Message object with parameters, check for /me messages, and delayed messages @@ -128,7 +128,7 @@ class TextBuffer(object): def add_message(self, txt, time=None, nickname=None, nick_color=None, history=None, user=None, highlight=False, - identifier=None, str_time=None, jid=None, ack=None): + identifier=None, str_time=None, jid=None, ack=0): """ Create a message and add it to the text buffer """ @@ -160,13 +160,23 @@ class TextBuffer(object): """ for i in range(len(self.messages) -1, -1, -1): msg = self.messages[i] + log.debug('\n%s ≠≠≠ %s', msg.identifier, old_id) if msg.identifier == old_id: return i return -1 def ack_message(self, old_id, jid): + """Mark a message as acked""" + return self.edit_ack(1, old_id, jid) + + def nack_message(self, error, old_id, jid): + """Mark a message as errored""" + return self.edit_ack(-1, old_id, jid, append=error) + + def edit_ack(self, value, old_id, jid, append=''): """ - Ack a message + Edit the ack status of a message, and optionally + append some text. """ i = self._find_message(old_id) if i == -1: @@ -177,7 +187,9 @@ class TextBuffer(object): (old_id, msg.jid, jid)) new_msg = list(msg) - new_msg[12] = True + new_msg[12] = value + if append: + new_msg[0] = new_msg[0] + append new_msg = Message(*new_msg) self.messages[i] = new_msg return new_msg diff --git a/src/theming.py b/src/theming.py index 81bc8820..ae71e48f 100755 --- a/src/theming.py +++ b/src/theming.py @@ -310,6 +310,7 @@ class Theme(object): CHAR_ERROR = '✖' CHAR_EMPTY = ' ' CHAR_ACK_RECEIVED = CHAR_OK + CHAR_NACK = CHAR_ERROR CHAR_COLUMN_ASC = ' ▲' CHAR_COLUMN_DESC = ' ▼' CHAR_ROSTER_ERROR = CHAR_ERROR @@ -324,6 +325,7 @@ class Theme(object): CHAR_ROSTER_NONE = '⇹' COLOR_CHAR_ACK = (2, -1) + COLOR_CHAR_NACK = (1, -1) COLOR_ROSTER_GAMING = (6, -1) COLOR_ROSTER_MOOD = (2, -1) diff --git a/src/windows/text_win.py b/src/windows/text_win.py index 380142bb..bdda721c 100644 --- a/src/windows/text_win.py +++ b/src/windows/text_win.py @@ -307,7 +307,10 @@ class TextWin(BaseTextWin): nick = truncate_nick(message.nickname) offset = 0 if message.ack: - offset += poopt.wcswidth(get_theme().CHAR_ACK_RECEIVED) + 1 + 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: @@ -361,7 +364,10 @@ class TextWin(BaseTextWin): if with_timestamps: self.write_time(msg.str_time) if msg.ack: - self.write_ack() + if msg.ack > 0: + self.write_ack() + else: + self.write_nack() if msg.me: self._win.attron(to_curses_attr(get_theme().COLOR_ME_MESSAGE)) self.addstr('* ') @@ -404,8 +410,11 @@ class TextWin(BaseTextWin): offset += ceil(log10(line.msg.revisions + 1)) if line.msg.ack: - offset += 1 + poopt.wcswidth( - get_theme().CHAR_ACK_RECEIVED) + if msg.ack > 0: + offset += 1 + poopt.wcswidth( + get_theme().CHAR_ACK_RECEIVED) + else: + offset += 1 + poopt.wcswidth(get_theme().CHAR_NACK) self.write_text(y, offset, line.prepend+line.msg.txt[line.start_pos:line.end_pos]) @@ -428,6 +437,13 @@ class TextWin(BaseTextWin): self._win.attroff(to_curses_attr(color)) self.addstr(' ') + 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(' ') + def write_nickname(self, nickname, color, highlight=False): """ Write the nickname, using the user's color -- cgit v1.2.3