Totale recode de l'affichage du texte, resultat : 0 BLINK (jamais, nada, quedalle), c'est plus simple (si si), et y'a plus de probleme de melange des messages entre salon. BEST COMMIT EVER. fixed #1171
This commit is contained in:
parent
41e7437d65
commit
fa4fbeb23c
3 changed files with 368 additions and 210 deletions
218
src/gui.py
218
src/gui.py
|
@ -38,24 +38,29 @@ from config import config
|
|||
from window import Window
|
||||
from user import User
|
||||
from room import Room
|
||||
from message import Message
|
||||
|
||||
from common import debug
|
||||
def doupdate():
|
||||
debug("doupdate")
|
||||
curses.doupdate()
|
||||
|
||||
class Gui(object):
|
||||
"""
|
||||
User interface using ncurses
|
||||
"""
|
||||
def __init__(self, stdscr=None, muc=None):
|
||||
self.room_number = 0
|
||||
self.init_curses(stdscr)
|
||||
self.stdscr = stdscr
|
||||
self.rooms = [Room('Info', '', self.next_room_number())]
|
||||
self.window = Window(stdscr)
|
||||
self.window.new_room(self.current_room())
|
||||
self.window.refresh(self.rooms)
|
||||
# self.window.new_room(self.current_room())
|
||||
# self.window.refresh(self.rooms)
|
||||
self.rooms = [Room('Info', '', self.window)]
|
||||
|
||||
self.muc = muc
|
||||
|
||||
self.commands = {
|
||||
'help': (self.command_help, _('OLOL, this is SOOO recursive')),
|
||||
'help': (self.command_help, _('That.')),
|
||||
'join': (self.command_join, _("""Usage: /join [room_name][/nick]
|
||||
[password]\nJoin: Join the specified room. You can specify a nickname after a
|
||||
slash (/). If no nickname is specified, you will use the default_nick in the
|
||||
|
@ -132,6 +137,8 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
"KEY_END": self.window.input.key_end,
|
||||
"KEY_HOME": self.window.input.key_home,
|
||||
"KEY_DOWN": self.window.input.key_down,
|
||||
"KEY_PPAGE": self.scroll_page_up,
|
||||
"KEY_NPAGE": self.scroll_page_down,
|
||||
"KEY_DC": self.window.input.key_dc,
|
||||
"KEY_F(5)": self.rotate_rooms_left,
|
||||
"KEY_F(6)": self.rotate_rooms_right,
|
||||
|
@ -154,12 +161,14 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
main loop waiting for the user to press a key
|
||||
"""
|
||||
while 1:
|
||||
stdscr.leaveok(1)
|
||||
curses.doupdate()
|
||||
# stdscr.leaveok(1)
|
||||
doupdate()
|
||||
try:
|
||||
key = stdscr.getkey()
|
||||
except:
|
||||
continue
|
||||
from common import debug
|
||||
# debug(str(key))
|
||||
if str(key) in self.key_func.keys():
|
||||
self.key_func[key]()
|
||||
elif str(key) == 'KEY_RESIZE':
|
||||
|
@ -186,13 +195,13 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
key = key+stdscr.getkey()
|
||||
self.window.do_command(key)
|
||||
|
||||
def next_room_number(self):
|
||||
"""
|
||||
Increments the room number and returns the new number
|
||||
"""
|
||||
nb = self.room_number
|
||||
self.room_number += 1
|
||||
return nb
|
||||
# def next_room_number(self):
|
||||
# """
|
||||
# Increments the room number and returns the new number
|
||||
# """
|
||||
# nb = self.room_number
|
||||
# self.room_number += 1
|
||||
# return nb
|
||||
|
||||
def current_room(self):
|
||||
"""
|
||||
|
@ -215,6 +224,7 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
"""
|
||||
curses.start_color()
|
||||
curses.noecho()
|
||||
curses.curs_set(0)
|
||||
# curses.cbreak()
|
||||
# curses.raw()
|
||||
curses.use_default_colors()
|
||||
|
@ -262,7 +272,7 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
"""
|
||||
join the specified room (muc), using the specified nick
|
||||
"""
|
||||
r = Room(room, nick, self.next_room_number())
|
||||
r = Room(room, nick, self.window)
|
||||
self.current_room().set_color_state(11)
|
||||
if self.current_room().nb == 0:
|
||||
self.rooms.append(r)
|
||||
|
@ -273,7 +283,7 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
break
|
||||
while self.current_room().nb != r.nb:
|
||||
self.rooms.insert(0, self.rooms.pop())
|
||||
self.window.new_room(r)
|
||||
# self.window.new_room(r)
|
||||
self.window.refresh(self.rooms)
|
||||
|
||||
def auto_completion(self):
|
||||
|
@ -298,6 +308,14 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
self.rooms.insert(0, self.rooms.pop())
|
||||
self.window.refresh(self.rooms)
|
||||
|
||||
def scroll_page_down(self, args=None):
|
||||
self.current_room().scroll_down()
|
||||
self.window.text_win.refresh(self.current_room())
|
||||
|
||||
def scroll_page_up(self, args=None):
|
||||
self.current_room().scroll_up()
|
||||
self.window.text_win.refresh(self.current_room())
|
||||
|
||||
def room_error(self, room, error, msg):
|
||||
"""
|
||||
Display the error on the room window
|
||||
|
@ -306,12 +324,10 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
code = error.getAttr('code')
|
||||
typ = error.getAttr('type')
|
||||
body = error.getTag('text').getData()
|
||||
self.add_info(room, _('Error: %(code)s-%(msg)s: %(body)s' %
|
||||
{'msg':msg, 'code':code, 'body':body}))
|
||||
self.add_message_to_room(room, _('Error: %(code)s-%(msg)s: %(body)s' %
|
||||
{'msg':msg, 'code':code, 'body':body}))
|
||||
if code == '401':
|
||||
self.add_info(room, _("""To provide a password in order
|
||||
to join the room, type "/join / password" (replace "password"
|
||||
by the real password)"""))
|
||||
room.add(_('To provide a password in order to join the room, type "/join / password" (replace "password" by the real password)'))
|
||||
|
||||
def room_message(self, stanza, date=None):
|
||||
"""
|
||||
|
@ -335,21 +351,27 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
subject = stanza.getSubject()
|
||||
if subject:
|
||||
if nick_from:
|
||||
self.add_info(room, _("""%(nick)s changed the subject to:
|
||||
%(subject)s""") % {'nick':nick_from, 'subject':subject}, date)
|
||||
self.add_message_to_room(room, _("%(nick)s changed the subject to: %(subject)s") % {'nick':nick_from, 'subject':subject}, date)
|
||||
# self.add_info(room, _("""%(nick)s changed the subject to:
|
||||
# %(subject)s""") % {'nick':nick_from, 'subject':subject}, date)
|
||||
else:
|
||||
self.add_info(room, _("The subject is: %(subject)s") %
|
||||
{'subject':subject}, date)
|
||||
self.add_message_to_room(room, _("The subject is: %(subject)s") % {'subject':subject}, date)
|
||||
# self.add_info(room, _("The subject is: %(subject)s") %
|
||||
# {'subject':subject}, date)
|
||||
room.topic = subject.encode('utf-8').replace('\n', '|')
|
||||
if room == self.current_room():
|
||||
self.window.topic_win.refresh(room.topic)
|
||||
elif body:
|
||||
if body.startswith('/me '):
|
||||
self.add_info(room, nick_from + ' ' + body[4:], date)
|
||||
# FIXME, it should be LIKE an information
|
||||
self.add_message_to_room(room, nick_from + ' ' + body[4:], date)
|
||||
# self.add_info(room, nick_from + ' ' + body[4:], date)
|
||||
else:
|
||||
self.add_message(room, nick_from, body, date, delayed)
|
||||
date = date if delayed == True else None
|
||||
self.add_message_to_room(room, body, date, nick_from)
|
||||
# self.add_message(room, nick_from, body, date, delayed)
|
||||
self.window.input.refresh()
|
||||
curses.doupdate()
|
||||
doupdate()
|
||||
|
||||
def room_presence(self, stanza):
|
||||
"""
|
||||
|
@ -374,10 +396,14 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
role))
|
||||
if from_nick.encode('utf-8') == room.own_nick:
|
||||
room.joined = True
|
||||
self.add_info(room, _("Your nickname is %s") % (from_nick))
|
||||
self.add_message_to_room(room, _("Your nickname is %s") % (from_nick))
|
||||
# self.add_info(room, _("Your nickname is %s") % (from_nick))
|
||||
else:
|
||||
self.add_info(room, _("%s is in the room") %
|
||||
(from_nick.encode('utf-8')))
|
||||
self.add_message_to_room(room, _("%s is in the room") %
|
||||
(from_nick# .encode('utf-8')
|
||||
))
|
||||
# self.add_info(room, _("%s is in the room") %
|
||||
# (from_nick.encode('utf-8')))
|
||||
else:
|
||||
change_nick = stanza.getStatusCode() == '303'
|
||||
kick = stanza.getStatusCode() == '307'
|
||||
|
@ -388,17 +414,18 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
show, status, role))
|
||||
hide_exit_join = config.get('hide_exit_join', -1)
|
||||
if hide_exit_join != 0:
|
||||
self.add_info(room, _("""%(nick)s joined the
|
||||
room %(roomname)s""") % {'nick':from_nick, 'roomname': room.name})
|
||||
self.add_message_to_room(room, _("%(nick)s joined the room %(roomname)s") % {'nick':from_nick, 'roomname': room.name})
|
||||
# self.add_info(room, _("%(nick)s joined the room %(roomname)s") % {'nick':from_nick, 'roomname': room.name})
|
||||
# nick change
|
||||
elif change_nick:
|
||||
if user.nick == room.own_nick:
|
||||
room.own_nick = stanza.getNick().encode('utf-8')
|
||||
user.change_nick(stanza.getNick())
|
||||
self.add_info(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()})
|
||||
# self.add_info(room,
|
||||
# _('%(old)s is now known as %(new)s') %
|
||||
# {'old':from_nick,
|
||||
# 'new':stanza.getNick()})
|
||||
# kick
|
||||
elif kick:
|
||||
room.users.remove(user)
|
||||
|
@ -413,72 +440,87 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
if from_nick == room.own_nick: # we are kicked
|
||||
room.disconnect()
|
||||
if by:
|
||||
self.add_info(room, _("""You have been kicked by
|
||||
%(by)s. Reason: %(reason)s""") % {'by':by, 'reason':reason})
|
||||
self.add_message_to_room(room, _("You have been kicked by %(by)s. Reason: %(reason)s") % {'by':by, 'reason':reason})
|
||||
# self.add_info(room, _("""You have been kicked by
|
||||
# %(by)s. Reason: %(reason)s""") % {'by':by, 'reason':reason})
|
||||
else:
|
||||
self.add_info(room, _("""You have been
|
||||
kicked. Reason: %s""") % (reason))
|
||||
self.add_message_to_room(room, _("You have been kicked. Reason: %s") % (reason))
|
||||
# self.add_info(room, _("""You have been
|
||||
# kicked. Reason: %s""") % (reason))
|
||||
else:
|
||||
if by:
|
||||
self.add_info(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, _("%(nick)s has been kicked by %(by)s. Reason: %(reason)s") % {'nick':from_nick, 'by':by, 'reason':reason})
|
||||
# self.add_info(room, _("""%(nick)s has been kicked
|
||||
# by %(by)s. Reason: %(reason)s""") %
|
||||
# {'nick':from_nick, 'by':by, 'reason':reason})
|
||||
else:
|
||||
self.add_info(room, _("""%(nick)s has been kicked.
|
||||
Reason: %(reason)s""") %
|
||||
{'nick':from_nick, 'reason':reason})
|
||||
self.add_message_to_room(room, _("%(nick)s has been kicked. Reason: %(reason)s") % {'nick':from_nick, 'reason':reason})
|
||||
# self.add_info(room, _("""%(nick)s has been kicked.
|
||||
# Reason: %(reason)s""") %
|
||||
# {'nick':from_nick, 'reason':reason})
|
||||
# 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):
|
||||
self.add_info(room, _('%s has left the room') % (from_nick))
|
||||
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):
|
||||
self.add_message_to_room(room, _('%s has left the room') % (from_nick))
|
||||
# self.add_info(room, _('%s has left the room') % (from_nick))
|
||||
# status change
|
||||
else:
|
||||
user.update(affiliation, show, status, role)
|
||||
hide_status_change = config.get('hide_status_change', -1)\
|
||||
if config.get('hide_status_change', -1) >= -1\
|
||||
else -1
|
||||
hide_status_change = config.get('hide_status_change', -1) if config.get('hide_status_change', -1) >= -1 else -1
|
||||
if hide_status_change == -1 or \
|
||||
user.has_talked_since(hide_status_change) or\
|
||||
user.nick == room.own_nick:
|
||||
self.add_info(room, _('%(nick)s changed his/her status : %(a)s, %(b)s, %(c)s, %(d)s') % {'nick':from_nick, 'a':affiliation, 'b':role, 'c':show, 'd':status})
|
||||
self.add_message_to_room(room, _('%(nick)s changed his/her status : %(a)s, %(b)s, %(c)s, %(d)s') % {'nick':from_nick, 'a':affiliation, 'b':role, 'c':show, 'd':status})
|
||||
# self.add_info(room, _('%(nick)s changed his/her status : %(a)s, %(b)s, %(c)s, %(d)s') % {'nick':from_nick, 'a':affiliation, 'b':role, 'c':show, 'd':status})
|
||||
if room == self.current_room():
|
||||
self.window.user_win.refresh(room.users)
|
||||
self.window.input.refresh()
|
||||
curses.doupdate()
|
||||
doupdate()
|
||||
|
||||
def add_info(self, room, info, date=None):
|
||||
def add_message_to_room(self, room, txt, time=None, nickname=None):
|
||||
"""
|
||||
add a new information in the specified room
|
||||
(displays it immediately AND saves it for redisplay
|
||||
in futur refresh)
|
||||
Add the message to the room and refresh the associated component
|
||||
of the interface
|
||||
"""
|
||||
if not date:
|
||||
date = datetime.now()
|
||||
msg = room.add_info(info, date)
|
||||
self.window.text_win.add_line(room, (date, msg))
|
||||
if room.name == self.current_room().name:
|
||||
self.window.text_win.refresh(room.name)
|
||||
self.window.input.refresh()
|
||||
curses.doupdate()
|
||||
|
||||
def add_message(self, room, nick_from, body, date=None, delayed=False):
|
||||
"""
|
||||
Just add a message
|
||||
"""
|
||||
if not date:
|
||||
date = datetime.now()
|
||||
color = room.add_message(nick_from, body, date)
|
||||
self.window.text_win.add_line(room, (date, nick_from.encode('utf-8'), body.encode('utf-8'), color))
|
||||
room.add_message(txt, time, nickname)
|
||||
if room == self.current_room():
|
||||
self.window.text_win.refresh(room.name)
|
||||
elif not delayed:
|
||||
self.window.text_win.refresh(room)
|
||||
# elif not delayed:
|
||||
else:
|
||||
self.window.info_win.refresh(self.rooms, self.current_room())
|
||||
|
||||
# TODO
|
||||
|
||||
# def add_info(self, room, info, date=None):
|
||||
# """
|
||||
# add a new information in the specified room
|
||||
# (displays it immediately AND saves it for redisplay
|
||||
# in futur refresh)
|
||||
# """
|
||||
# if not date:
|
||||
# date = datetime.now()
|
||||
# msg = room.add_info(info, date)
|
||||
# self.window.text_win.add_line(room, (date, msg))
|
||||
# if room.name == self.current_room().name:
|
||||
# self.window.text_win.refresh(room.name)
|
||||
# self.window.input.refresh()
|
||||
# doupdate()
|
||||
|
||||
# def add_message(self, room, nick_from, body, date=None, delayed=False):
|
||||
# """
|
||||
# Just add a message
|
||||
# """
|
||||
# if not date:
|
||||
# date = datetime.now()
|
||||
# color = room.add_message(nick_from, body, date)
|
||||
# self.window.text_win.add_line(room, (date, nick_from.encode('utf-8'), body.encode('utf-8'), color))
|
||||
# if room == self.current_room():
|
||||
# self.window.text_win.refresh(room.name)
|
||||
# elif not delayed:
|
||||
# self.window.info_win.refresh(self.rooms, self.current_room())
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
Execute the /command or just send the line on the current room
|
||||
|
@ -496,11 +538,12 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
func(args)
|
||||
return
|
||||
else:
|
||||
self.add_info(self.current_room(), _("Error: unknown command (%s)") % (command))
|
||||
self.add_message_to_room(self.current_room(), _("Error: unknown command (%s)") % (command))
|
||||
# self.add_info(self.current_room(), _("Error: unknown command (%s)") % (command))
|
||||
elif self.current_room().name != 'Info':
|
||||
self.muc.send_message(self.current_room().name, line)
|
||||
self.window.input.refresh()
|
||||
curses.doupdate()
|
||||
doupdate()
|
||||
|
||||
def command_help(self, args):
|
||||
"""
|
||||
|
@ -517,7 +560,8 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
msg = self.commands[args[0]][1]
|
||||
else:
|
||||
msg = _('Unknown command: %s') % args[0]
|
||||
self.add_info(room, msg)
|
||||
self.add_message_to_room(room, msg)
|
||||
# self.add_info(room, msg)
|
||||
|
||||
def command_win(self, args):
|
||||
"""
|
||||
|
@ -648,7 +692,8 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
config.set_and_save(option, value)
|
||||
msg = "%s=%s" % (option, value)
|
||||
room = self.current_room()
|
||||
self.add_info(room, msg)
|
||||
self.add_message_to_room(room, msg)
|
||||
# self.add_info(room, msg)
|
||||
|
||||
def command_show(self, args):
|
||||
"""
|
||||
|
@ -762,7 +807,8 @@ Avail: Sets your availability to available and (optional) sets your status
|
|||
Displays an informational message in the "Info" room window
|
||||
"""
|
||||
room = self.get_room_by_name("Info")
|
||||
self.add_info(room, msg)
|
||||
self.add_message_to_room(room, msg)
|
||||
# self.add_info(room, msg)
|
||||
|
||||
def command_quit(self, args):
|
||||
"""
|
||||
|
|
109
src/room.py
109
src/room.py
|
@ -21,61 +21,88 @@ from datetime import datetime
|
|||
from random import randrange
|
||||
from config import config
|
||||
from logging import logger
|
||||
from message import Message
|
||||
|
||||
class Room(object):
|
||||
"""
|
||||
"""
|
||||
def __init__(self, name, nick, number):
|
||||
number = 0
|
||||
def __init__(self, name, nick, window):
|
||||
self.name = name
|
||||
self.own_nick = nick
|
||||
self.color_state = 11 # color used in RoomInfo
|
||||
self.nb = number # number used in RoomInfo
|
||||
self.nb = Room.number # number used in RoomInfo
|
||||
Room.number += 1
|
||||
self.joined = False # false until self presence is received
|
||||
self.users = []
|
||||
self.lines = [] # (time, nick, msg) or (time, info)
|
||||
self.users = [] # User objects
|
||||
self.messages = [] # Message objects
|
||||
self.topic = ''
|
||||
self.window = window
|
||||
self.pos = 0 # offset
|
||||
|
||||
def scroll_up(self):
|
||||
self.pos += 14
|
||||
|
||||
def scroll_down(self):
|
||||
self.pos -= 14
|
||||
if self.pos <= 0:
|
||||
self.pos = 0
|
||||
|
||||
def disconnect(self):
|
||||
self.joined = False
|
||||
|
||||
def add_message(self, nick, msg, date=None):
|
||||
if not date:
|
||||
date = datetime.now()
|
||||
color = None
|
||||
self.set_color_state(12)
|
||||
if nick != self.own_nick and self.joined: # do the highlight thing
|
||||
if self.own_nick in msg:
|
||||
self.set_color_state(13)
|
||||
color = 3
|
||||
else:
|
||||
highlight_words = config.get('highlight_on', '').split(':')
|
||||
for word in highlight_words:
|
||||
if word.lower() in msg.lower() and word != '':
|
||||
self.set_color_state(13)
|
||||
color = 3
|
||||
break
|
||||
if not msg:
|
||||
logger.info('msg is None..., %s' % (nick))
|
||||
return
|
||||
self.lines.append((date, nick.encode('utf-8'),
|
||||
msg.encode('utf-8'), color))
|
||||
user = self.get_user_by_name(nick)
|
||||
if user:
|
||||
user.set_last_talked(date)
|
||||
if self.joined: # log only NEW messages, not the history received on join
|
||||
logger.message(self.name, nick.encode('utf-8'), msg.encode('utf-8'))
|
||||
return color
|
||||
def add_message(self, txt, time=None, nickname=None):
|
||||
"""
|
||||
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
|
||||
in the room anymore
|
||||
"""
|
||||
user = self.get_user_by_name(nickname) if nickname is not None else None
|
||||
time = time if time is not None else datetime.now()
|
||||
from common import debug
|
||||
# debug("add_message: %s, %s, %s, %s" % (str(txt), str(time), str(nickname), str(user)))
|
||||
self.messages.append(Message(txt, time, nickname, user))
|
||||
|
||||
def add_info(self, info, date=None):
|
||||
""" info, like join/quit/status messages"""
|
||||
if not date:
|
||||
date = datetime.now()
|
||||
try:
|
||||
self.lines.append((date, info.encode('utf-8')))
|
||||
return info.encode('utf-8')
|
||||
except:
|
||||
self.lines.append((date, info))
|
||||
return info
|
||||
# def add_message(nick, msg, date=None)
|
||||
# TODO: limit the message kept in memory (configurable)
|
||||
|
||||
# if not date:
|
||||
# date = datetime.now()
|
||||
# color = None
|
||||
# self.set_color_state(12)
|
||||
# if nick != self.own_nick and self.joined: # do the highlight thing
|
||||
# if self.own_nick in msg:
|
||||
# self.set_color_state(13)
|
||||
# color = 3
|
||||
# else:
|
||||
# highlight_words = config.get('highlight_on', '').split(':')
|
||||
# for word in highlight_words:
|
||||
# if word.lower() in msg.lower() and word != '':
|
||||
# self.set_color_state(13)
|
||||
# color = 3
|
||||
# break
|
||||
# if not msg:
|
||||
# logger.info('msg is None..., %s' % (nick))
|
||||
# return
|
||||
# self.lines.append((date, nick.encode('utf-8'),
|
||||
# msg.encode('utf-8'), color))
|
||||
# user = self.get_user_by_name(nick)
|
||||
# if user:
|
||||
# user.set_last_talked(date)
|
||||
# if self.joined: # log only NEW messages, not the history received on join
|
||||
# logger.message(self.name, nick.encode('utf-8'), msg.encode('utf-8'))
|
||||
# return color
|
||||
|
||||
# def add_info(self, info, date=None):
|
||||
# """ info, like join/quit/status messages"""
|
||||
# if not date:
|
||||
# date = datetime.now()
|
||||
# try:
|
||||
# self.lines.append((date, info.encode('utf-8')))
|
||||
# return info.encode('utf-8')
|
||||
# except:
|
||||
# self.lines.append((date, info))
|
||||
# return info
|
||||
|
||||
def get_user_by_name(self, nick):
|
||||
for user in self.users:
|
||||
|
|
251
src/window.py
251
src/window.py
|
@ -40,7 +40,9 @@ class Win(object):
|
|||
# V_/_
|
||||
print parent_win, parent_win.height, parent_win.width, height, width, y, x
|
||||
raise
|
||||
self.win.idlok(1)
|
||||
self.win.leaveok(1)
|
||||
self.win.syncok(0)
|
||||
|
||||
def refresh(self):
|
||||
self.win.noutrefresh()
|
||||
|
@ -50,7 +52,7 @@ class UserList(Win):
|
|||
Win.__init__(self, height, width, y, x, parent_win)
|
||||
self.visible = visible
|
||||
self.win.attron(curses.color_pair(2))
|
||||
self.win.vline(0, 0, curses.ACS_VLINE, self.height)
|
||||
# self.win.vline(0, 0, curses.ACS_VLINE, self.height)
|
||||
self.win.attroff(curses.color_pair(2))
|
||||
self.color_role = {'moderator': 3,
|
||||
'participant':2,
|
||||
|
@ -66,7 +68,7 @@ class UserList(Win):
|
|||
def refresh(self, users):
|
||||
if not self.visible:
|
||||
return
|
||||
self.win.clear()
|
||||
self.win.erase()
|
||||
y = 0
|
||||
for user in users:
|
||||
try:
|
||||
|
@ -105,7 +107,7 @@ class Topic(Win):
|
|||
def refresh(self, room_name):
|
||||
if not self.visible:
|
||||
return
|
||||
self.win.clear()
|
||||
self.win.erase()
|
||||
try:
|
||||
self.win.addnstr(0, 0, room_name + " "*(self.width-len(room_name)), self.width
|
||||
, curses.color_pair(1))
|
||||
|
@ -125,7 +127,7 @@ class RoomInfo(Win):
|
|||
return
|
||||
def compare_room(a, b):
|
||||
return a.nb - b.nb
|
||||
self.win.clear()
|
||||
self.win.erase()
|
||||
try:
|
||||
self.win.addnstr(0, 0, current.name+" [", self.width
|
||||
,curses.color_pair(1))
|
||||
|
@ -149,15 +151,21 @@ class RoomInfo(Win):
|
|||
pass
|
||||
self.win.refresh()
|
||||
|
||||
class TextWin(object):
|
||||
class TextWin(Win):
|
||||
"""
|
||||
keep a dict of {winname: window}
|
||||
when a new message is received in a room, just add
|
||||
the line at the bottom (and scroll if needed)
|
||||
when the current room is changed, just refresh the
|
||||
associated window
|
||||
When the term is resized, rebuild ALL the windows
|
||||
(the complete lines lists are keeped in the Room class)
|
||||
# keep a dict of {winname: window}
|
||||
# when a new message is received in a room, just add
|
||||
# the line at the bottom (and scroll if needed)
|
||||
# when the current room is changed, just refresh the
|
||||
# associated window
|
||||
# When the term is resized, rebuild ALL the windows
|
||||
# (the complete lines lists are keeped in the Room class)
|
||||
Nope, don't do that anymore.
|
||||
Weechat is doing it the easy way, and it's working, there's no
|
||||
reason poezio can't do it (it's python, but that shouldn't change
|
||||
anything)
|
||||
Just keep ONE single window for the text area and rewrite EVERYTHING
|
||||
on each change.
|
||||
"""
|
||||
def __init__(self, height, width, y, x, parent_win, visible):
|
||||
self.visible = visible
|
||||
|
@ -166,79 +174,156 @@ class TextWin(object):
|
|||
self.y = y
|
||||
self.x = x
|
||||
self.parent_win = parent_win
|
||||
self.wins = {}
|
||||
Win.__init__(self, height, width, y, x, parent_win)
|
||||
|
||||
def redraw(self, room):
|
||||
def refresh(self, room):
|
||||
"""
|
||||
called when the buffer changes or is
|
||||
resized (a complete redraw is needed)
|
||||
"""
|
||||
if not self.visible:
|
||||
return
|
||||
win = self.wins[room.name].win
|
||||
win.clear()
|
||||
win.move(0, 0)
|
||||
for line in room.lines:
|
||||
self.add_line(room, line)
|
||||
# TODO: keep a position in the room, and display
|
||||
# the messages from this position (can be used to scroll)
|
||||
from common import debug
|
||||
y = 0
|
||||
self.win.erase()
|
||||
if room.pos != 0:
|
||||
messages = room.messages[-self.height - room.pos : -room.pos]
|
||||
else:
|
||||
messages = room.messages[-self.height:]
|
||||
for message in messages:
|
||||
# debug(str(message))
|
||||
self.write_time(y, message.time)
|
||||
if message.nickname is not None:
|
||||
x = self.write_nickname(y, message.nickname.encode('utf-8'), message.user)
|
||||
else:
|
||||
x = 11
|
||||
self.win.attron(curses.color_pair(8))
|
||||
y += self.write_text(y, x, message.txt)
|
||||
if message.nickname is None:
|
||||
self.win.attroff(curses.color_pair(8))
|
||||
# self.win.addnstr(y, x, message.txt, 40)
|
||||
# self.win
|
||||
y += 1
|
||||
self.win.refresh()
|
||||
|
||||
def refresh(self, winname):
|
||||
if self.visible:
|
||||
self.wins[winname].refresh()
|
||||
def write_text(self, y, x, txt):
|
||||
"""
|
||||
return the number of line written, -1
|
||||
"""
|
||||
txt = txt.encode('utf-8')
|
||||
l = 0
|
||||
while txt != '':
|
||||
debug(txt)
|
||||
if txt[:self.width-x].find('\n') != -1:
|
||||
limit = txt[:self.width-x].find('\n')
|
||||
debug("=================="+str(limit))
|
||||
else:
|
||||
limit = self.width-x
|
||||
self.win.addnstr(y+l, x, txt, limit)
|
||||
txt = txt[limit+1:]
|
||||
l += 1
|
||||
return l-1
|
||||
|
||||
def add_line(self, room, line):
|
||||
if not self.visible:
|
||||
return
|
||||
win = self.wins[room.name].win
|
||||
users = room.users
|
||||
win.addstr('\n['+line[0].strftime("%H"))
|
||||
win.attron(curses.color_pair(9))
|
||||
win.addstr(':')
|
||||
win.attroff(curses.color_pair(9))
|
||||
win.addstr(line[0].strftime('%M'))
|
||||
win.attron(curses.color_pair(9))
|
||||
win.addstr(':')
|
||||
win.attroff(curses.color_pair(9))
|
||||
win.addstr(line[0].strftime('%S') + "] ")
|
||||
if len(line) == 2:
|
||||
try:
|
||||
win.attron(curses.color_pair(8))
|
||||
win.addstr(line[1])
|
||||
win.attroff(curses.color_pair(8))
|
||||
except:pass
|
||||
elif len(line) == 4:
|
||||
for user in users:
|
||||
if user.nick == line[1]:
|
||||
break
|
||||
try:
|
||||
length = len('['+line[0].strftime("%H:%M:%S") + "] <")
|
||||
if line[1]:
|
||||
win.attron(curses.color_pair(user.color))
|
||||
win.addstr(line[1])
|
||||
win.attroff(curses.color_pair(user.color))
|
||||
win.addstr("> ")
|
||||
if line[3]:
|
||||
win.attron(curses.color_pair(line[3]))
|
||||
win.addstr(line[2])
|
||||
if line[3]:
|
||||
win.attroff(curses.color_pair(line[3]))
|
||||
except:pass
|
||||
def write_nickname(self, y, nickname, user):
|
||||
"""
|
||||
Write the nickname, using the user's color
|
||||
and return the number of written characters
|
||||
"""
|
||||
if user:
|
||||
self.win.attron(curses.color_pair(user.color))
|
||||
self.win.addstr(y, 11, nickname)
|
||||
if user:
|
||||
self.win.attroff(curses.color_pair(user.color))
|
||||
self.win.addnstr(y, 11+len(nickname.decode('utf-8')), "> ", 2)
|
||||
return len(nickname.decode('utf-8')) + 13
|
||||
|
||||
def new_win(self, winname):
|
||||
newwin = Win(self.height, self.width, self.y, self.x, self.parent_win)
|
||||
newwin.win.idlok(True)
|
||||
newwin.win.scrollok(True)
|
||||
newwin.win.leaveok(1)
|
||||
self.wins[winname] = newwin
|
||||
def write_time(self, y, time):
|
||||
"""
|
||||
Write the date on the yth line of the window
|
||||
"""
|
||||
self.win.addnstr(y, 0, '['+time.strftime("%H"), 3)
|
||||
self.win.attron(curses.color_pair(9))
|
||||
self.win.addnstr(y, 3, ':', 1)
|
||||
self.win.attroff(curses.color_pair(9))
|
||||
self.win.addstr(y, 4, time.strftime('%M'), 2)
|
||||
self.win.attron(curses.color_pair(9))
|
||||
self.win.addstr(y, 6, ':', 1)
|
||||
self.win.attroff(curses.color_pair(9))
|
||||
self.win.addstr(y, 7, time.strftime('%S') + "] ", 3)
|
||||
|
||||
def resize(self, height, width, y, x, stdscr, visible):
|
||||
self.visible = visible
|
||||
if not visible:
|
||||
return
|
||||
for winname in self.wins.keys():
|
||||
self.wins[winname]._resize(height, width, y, x, stdscr)
|
||||
self.wins[winname].win.idlok(True)
|
||||
self.wins[winname].win.scrollok(True)
|
||||
self.wins[winname].win.leaveok(1)
|
||||
self._resize(height, width, y, x, stdscr)
|
||||
|
||||
# def redraw(self, room):
|
||||
# """
|
||||
# called when the buffer changes or is
|
||||
# resized (a complete redraw is needed)
|
||||
# """
|
||||
# if not self.visible:
|
||||
# return
|
||||
# win = self.wins[room.name].win
|
||||
# win.clear()
|
||||
# win.move(0, 0)
|
||||
# for line in room.lines:
|
||||
# self.add_line(room, line)
|
||||
|
||||
# def refresh(self, winname):
|
||||
# self.
|
||||
# if self.visible:
|
||||
# self.wins[winname].refresh()
|
||||
|
||||
# def add_line(self, room, line):
|
||||
# if not self.visible:
|
||||
# return
|
||||
# win = self.wins[room.name].win
|
||||
# users = room.users
|
||||
# win.addstr('\n['+line[0].strftime("%H"))
|
||||
# win.attron(curses.color_pair(9))
|
||||
# win.addstr(':')
|
||||
# win.attroff(curses.color_pair(9))
|
||||
# win.addstr(line[0].strftime('%M'))
|
||||
# win.attron(curses.color_pair(9))
|
||||
# win.addstr(':')
|
||||
# win.attroff(curses.color_pair(9))
|
||||
# win.addstr(line[0].strftime('%S') + "] ")
|
||||
# if len(line) == 2:
|
||||
# try:
|
||||
# win.attron(curses.color_pair(8))
|
||||
# win.addstr(line[1])
|
||||
# win.attroff(curses.color_pair(8))
|
||||
# except:pass
|
||||
# elif len(line) == 4:
|
||||
# for user in users:
|
||||
# if user.nick == line[1]:
|
||||
# break
|
||||
# try:
|
||||
# length = len('['+line[0].strftime("%H:%M:%S") + "] <")
|
||||
# if line[1]:
|
||||
# win.attron(curses.color_pair(user.color))
|
||||
# win.addstr(line[1])
|
||||
# win.attroff(curses.color_pair(user.color))
|
||||
# win.addstr("> ")
|
||||
# if line[3]:
|
||||
# win.attron(curses.color_pair(line[3]))
|
||||
# win.addstr(line[2])
|
||||
# if line[3]:
|
||||
# win.attroff(curses.color_pair(line[3]))
|
||||
# except:pass
|
||||
|
||||
# def new_win(self, winname):
|
||||
# newwin = Win(self.height, self.width, self.y, self.x, self.parent_win)
|
||||
# newwin.win.idlok(True)
|
||||
# newwin.win.scrollok(True)
|
||||
# newwin.win.leaveok(1)
|
||||
# self.wins[winname] = newwin
|
||||
|
||||
# def resize(self, height, width, y, x, stdscr, visible):
|
||||
# self.visible = visible
|
||||
# if not visible:
|
||||
# return
|
||||
# for winname in self.wins.keys():
|
||||
# self.wins[winname]._resize(height, width, y, x, stdscr)
|
||||
# self.wins[winname].win.idlok(True)
|
||||
# self.wins[winname].win.scrollok(True)
|
||||
# self.wins[winname].win.leaveok(1)
|
||||
|
||||
class Input(Win):
|
||||
"""
|
||||
|
@ -483,10 +568,10 @@ class Input(Win):
|
|||
def refresh(self):
|
||||
if not self.visible:
|
||||
return
|
||||
self.win.noutrefresh()
|
||||
self.win.refresh()
|
||||
|
||||
def clear_text(self):
|
||||
self.win.clear()
|
||||
self.win.erase()
|
||||
|
||||
class Window(object):
|
||||
"""
|
||||
|
@ -542,8 +627,8 @@ class Window(object):
|
|||
'room' is the current one
|
||||
"""
|
||||
room = rooms[0] # get current room
|
||||
self.text_win.redraw(room)
|
||||
self.text_win.refresh(room.name)
|
||||
# self.text_win.redraw(room)
|
||||
self.text_win.refresh(room)
|
||||
self.user_win.refresh(room.users)
|
||||
self.topic_win.refresh(room.topic)
|
||||
self.info_win.refresh(rooms, room)
|
||||
|
@ -553,5 +638,5 @@ class Window(object):
|
|||
self.input.do_command(key)
|
||||
self.input.refresh()
|
||||
|
||||
def new_room(self, room):
|
||||
self.text_win.new_win(room.name)
|
||||
# def new_room(self, room):
|
||||
# self.text_win.new_win(room.name)
|
||||
|
|
Loading…
Reference in a new issue