Mor colored information message, also finish the theme 'engine'. fixed #1537

parent 3d278f78
......@@ -484,9 +484,9 @@ class Gui(object):
hide_exit_join = config.get('hide_exit_join', -1)
if hide_exit_join != 0:
if not jid:
self.add_message_to_room(room, _("%(nick)s joined the room") % {'nick':from_nick})
self.add_message_to_room(room, _("%(spec)s [%(nick)s] joined the room") % {'nick':from_nick, 'spec':theme.CHAR_JOIN}, colorized=True)
else:
self.add_message_to_room(room, _("%(nick)s (%(jid)s) joined the room") % {'nick':from_nick, 'jid':jid})
self.add_message_to_room(room, _("%(spec)s [%(nick)s] (%(jid)s) joined the room") % {'spec':theme.CHAR_JOIN, 'nick':from_nick, 'jid':jid}, colorized=True)
# nick change
elif change_nick:
if user.nick == room.own_nick:
......@@ -496,11 +496,11 @@ class Gui(object):
if _room.jid is not None and is_jid_the_same(_room.jid, room.name):
_room.own_nick = stanza.getNick()
user.change_nick(stanza.getNick())
self.add_message_to_room(room, _('%(old)s is now known as %(new)s') % {'old':from_nick, 'new':stanza.getNick()})
self.add_message_to_room(room, _('[%(old)s] is now known as [%(new)s]') % {'old':from_nick, 'new':stanza.getNick()}, colorized=True)
# rename the private tabs if needed
private_room = self.get_room_by_name(stanza.getFrom())
if private_room:
self.add_message_to_room(private_room, _('%(old_nick)s is now known as %(new_nick)s') % {'old_nick':from_nick, 'new_nick':stanza.getNick()})
self.add_message_to_room(private_room, _('[%(old_nick)s] is now known as [%(new_nick)s]') % {'old_nick':from_nick, 'new_nick':stanza.getNick()}, colorized=True)
new_jid = private_room.name.split('/')[0]+'/'+stanza.getNick()
private_room.jid = new_jid
private_room.name = new_jid
......@@ -519,29 +519,29 @@ class Gui(object):
if from_nick == room.own_nick: # we are kicked
room.disconnect()
if by:
self.add_message_to_room(room, _("You have been kicked by %(by)s. Reason: %(reason)s") % {'by':by, 'reason':reason})
self.add_message_to_room(room, _("%(spec) [You] have been kicked by [%(by)s]. Reason: {%(reason)s}") % {'spec': theme.CHAR_KICK, 'by':by, 'reason':reason}, colorized=True)
else:
self.add_message_to_room(room, _("You have been kicked. Reason: %s") % (reason))
self.add_message_to_room(room, _("%(spec)s [You] have been kicked. Reason: %(reason)s") % {'reason':reason, 'spec':theme.CHAR_KICK}, colorized=True)
# try to auto-rejoin
if config.get('autorejoin', 'false') == 'true':
self.muc.join_room(room.name, room.own_nick)
else:
if by:
self.add_message_to_room(room, _("%(nick)s has been kicked by %(by)s. Reason: %(reason)s") % {'nick':from_nick, 'by':by, 'reason':reason})
self.add_message_to_room(room, _("%(spec)s [%(nick)s] has been kicked by %(by)s. Reason: %(reason)s") % {'spec':theme.CHAR_KICK, 'nick':from_nick, 'by':by, 'reason':reason}, colorized=True)
else:
self.add_message_to_room(room, _("%(nick)s has been kicked. Reason: %(reason)s") % {'nick':from_nick, 'reason':reason})
self.add_message_to_room(room, _("%(spec)s [%(nick)s] has been kicked. Reason: %(reason)s") % {'nick':from_nick, 'reason':reason, 'spec':theme.CHAR_KICK}, colorized=True)
# user quit
elif status == 'offline' or role == 'none':
room.users.remove(user)
hide_exit_join = config.get('hide_exit_join', -1) if config.get('hide_exit_join', -1) >= -1 else -1
if hide_exit_join == -1 or user.has_talked_since(hide_exit_join):
if not jid:
self.add_message_to_room(room, _('%s has left the room') % (from_nick))
self.add_message_to_room(room, _('%(spec)s [%(nick)s] has left the room') % {'nick':from_nick, 'spec':theme.CHAR_QUIT}, colorized=True)
else:
self.add_message_to_room(room, _('%(nick)s (%(jid)s) has left the room') % {'nick':from_nick, 'jid':jid})
self.add_message_to_room(room, _('%(spec)s [%(nick)s] (%(jid)s) has left the room') % {'spec':theme.CHAR_QUIT, 'nick':from_nick, 'jid':jid}, colorized=True)
private_room = self.get_room_by_name(stanza.getFrom())
if private_room:
self.add_message_to_room(private_room, _('%s has left the room') % (from_nick))
self.add_message_to_room(private_room, _('%(spec)s [%(nick)s] has left the room') % {'nick':from_nick, 'spec':theme.CHAR_KICK}, colorized=True)
# status change
else:
# build the message
......@@ -576,14 +576,14 @@ class Gui(object):
self.window.input.refresh()
doupdate()
def add_message_to_room(self, room, txt, time=None, nickname=None):
def add_message_to_room(self, room, txt, time=None, nickname=None, colorized=False):
"""
Add the message to the room and refresh the associated component
of the interface
"""
if room != self.current_room():
room.add_line_separator()
room.add_message(txt, time, nickname)
room.add_message(txt, time, nickname, colorized)
if room == self.current_room():
self.window.text_win.refresh(room)
else:
......
......@@ -21,21 +21,25 @@ from datetime import datetime
class Message(object):
"""
A message with all the associated data (nickname, time, color, etc)
The color can be a single number OR a list of numbers, for
specials cases like join or quit messages.
"""
def __init__(self, txt, time=None, nickname=None, user=None, color=None):
def __init__(self, txt, time=None, nickname=None, user=None, color=None, colorized=False):
"""
time is a datetime object, None means 'now'.
If no nickname is specified, it's an information.
user is an User object (used for the color, etc)
"""
self.txt = txt
self.nickname = nickname
self.time = time
self.user = user
self.color = color
self.colorized = colorized
def __repr__(self):
return "<Message txt=%s, nickname=%s, time=%s, user=%s>" % (self.txt, self.nickname, str(self.time), str(self.user))
return "<Message txt=%s, nickname=%s, time=%s, user=%s, colorized=%s>" % (self.txt, self.nickname, str(self.time), str(self.user), self.colorized)
def __str__(self):
return self.__repr__()
......@@ -43,6 +47,8 @@ class Line(object):
"""
A line, corresponding to ONE row of the text area.
A message is composed of ONE line or MORE.
The same particularity for colors in Message class applies
here too.
Example:
Text area limit text area limit
......@@ -67,10 +73,11 @@ class Line(object):
Line(None, None, None, "informations here:", 0, 23)
Line(None, None, None, "http://blablablabla", 0, 23)
"""
def __init__(self, nickname, nickname_color, time, text, text_color, text_offset):
def __init__(self, nickname, nickname_color, time, text, text_color, text_offset, colorized=False):
self.nickname = nickname
self.nickname_color = nickname_color
self.time = time
self.text = text
self.text_color = text_color
self.text_offset = text_offset
self.colorized = colorized
......@@ -91,7 +91,7 @@ class Room(object):
break
return color
def add_message(self, txt, time=None, nickname=None):
def add_message(self, txt, time=None, nickname=None, colorized=False):
"""
Note that user can be None even if nickname is not None. It happens
when we receive an history message said by someone who is not
......@@ -116,7 +116,7 @@ class Room(object):
if time: # History messages are colored to be distinguished
color = theme.COLOR_INFORMATION_TEXT
time = time if time is not None else datetime.now()
self.messages.append(Message(txt, time, nickname, user, color))
self.messages.append(Message(txt, time, nickname, user, color, colorized))
def remove_line_separator(self):
"""
......
......@@ -42,6 +42,10 @@ COLOR_USER_PARTICIPANT = 73
COLOR_USER_NONE = 80
COLOR_USER_MODERATOR = 77
# The character printed in color (COLOR_STATUS_*) before the nickname
# in the user list
CHAR_STATUS = ' '
# Separators
COLOR_VERTICAL_SEPARATOR = 73
COLOR_NEW_TEXT_SEPARATOR = 75
......@@ -77,8 +81,24 @@ COLOR_TOPIC_BAR = 15
COLOR_PRIVATE_ROOM_BAR = 33
COLOR_SCROLLABLE_NUMBER = 16
# Chars
STATUS_CHAR = ' '
# Strings for special messages (like join, quit, nick change, etc)
# Special messages
CHAR_JOIN = '---->'
CHAR_QUIT = '<----'
CHAR_KICK = '-!-'
COLOR_JOIN_CHAR = 73
COLOR_QUIT_CHAR = 77
COLOR_KICK_CHAR = 77
# words between ()
COLOR_CURLYBRACKETED_WORD = 72
# words between {}
COLOR_ACCOLADE_WORD = 74
# words between []
COLOR_BRACKETED_WORD = 73
def init_colors():
"""
......@@ -123,7 +143,7 @@ def reload_theme():
except: # TODO warning: theme not found
return
for var in dir(theme):
if var.startswith('COLOR_') or var.startswith('STATUS_'):
if var.startswith('COLOR_') or var.startswith('CHAR_'):
globals()[var] = getattr(theme, var)
if __name__ == '__main__':
......
......@@ -102,7 +102,7 @@ class UserList(Win):
except KeyError:
show_col = theme.COLOR_STATUS_NONE
self.win.attron(curses.color_pair(show_col))
self.win.addnstr(y, 0, theme.STATUS_CHAR, 1)
self.win.addnstr(y, 0, theme.CHAR_STATUS, 1)
self.win.attroff(curses.color_pair(show_col))
self.win.attron(curses.color_pair(role_col))
try:
......@@ -267,7 +267,8 @@ class TextWin(Win):
l = Line(nick, color,
time,
txt[:limit], message.color,
offset)
offset,
message.colorized)
lines.append(l)
if this_line_was_broken_by_space:
txt = txt[limit+1:] # jump the space at the start of the line
......@@ -308,7 +309,7 @@ class TextWin(Win):
self.write_time(line.time)
if line.nickname is not None:
self.write_nickname(line.nickname.encode('utf-8'), line.nickname_color)
self.write_text(y, line.text_offset, line.text, line.text_color)
self.write_text(y, line.text_offset, line.text, line.text_color, line.colorized)
y += 1
self.win.refresh()
g_lock.release()
......@@ -320,11 +321,12 @@ class TextWin(Win):
self.win.addstr(' -'*(self.width/2))
self.win.attroff(curses.color_pair(theme.COLOR_NEW_TEXT_SEPARATOR))
def write_text(self, y, x, txt, color):
def write_text(self, y, x, txt, color, colorized):
"""
write the text of a line.
"""
txt = txt.encode('utf-8')
if not colorized:
if color:
self.win.attron(curses.color_pair(color))
try:
......@@ -334,6 +336,35 @@ class TextWin(Win):
if color:
self.win.attroff(curses.color_pair(color))
else: # Special messages like join or quit
from common import debug
special_words = {
theme.CHAR_JOIN: theme.COLOR_JOIN_CHAR,
theme.CHAR_QUIT: theme.COLOR_QUIT_CHAR,
theme.CHAR_KICK: theme.COLOR_KICK_CHAR,
}
for word in txt.split():
if word in special_words.keys():
self.win.attron(curses.color_pair(special_words[word]))
self.win.addstr(word)
self.win.attroff(curses.color_pair(special_words[word]))
elif word.startswith('(') and word.endswith(')'):
self.win.addstr('(', curses.color_pair(color))
self.win.addstr(word[1:-1], curses.color_pair(theme.COLOR_CURLYBRACKETED_WORD))
self.win.addstr(')', curses.color_pair(color))
elif word.startswith('{') and word.endswith('}'):
self.win.addstr(word[1:-1], curses.color_pair(theme.COLOR_ACCOLADE_WORD))
elif word.startswith('[') and word.endswith(']'):
self.win.addstr(word[1:-1], curses.color_pair(theme.COLOR_BRACKETED_WORD))
else:
self.win.attron(curses.color_pair(color))
self.win.addstr(word)
self.win.attroff(curses.color_pair(color))
try:
self.win.addstr(' ')
except:
pass
def write_nickname(self, nickname, color):
"""
Write the nickname, using the user's color
......@@ -712,10 +743,7 @@ class Input(Win):
Refresh the line onscreen, from the pos and pos_line
"""
self.clear_text()
try: # FIXME: this try should NOT be needed
self.win.addstr(self.text[self.line_pos:self.line_pos+self.width-1].encode('utf-8'))
except:
pass
self.win.move(0, self.pos)
self.refresh()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment