From 038038b728f7e6c4aaf5e24c85bf7047532a3aad Mon Sep 17 00:00:00 2001 From: "louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13" Date: Wed, 27 Jan 2010 17:02:13 +0000 Subject: toute nouvelle facon d'afficher le texte. Les accents fonctionnent. TODO: recoder le textpad from scratch, parce qu'il craint comme ca. --- src/gui.py | 67 ++++++++++++++++++------------ src/poezio.cfg | 2 +- src/window.py | 126 ++++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 124 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/gui.py b/src/gui.py index 38490678..366f0692 100644 --- a/src/gui.py +++ b/src/gui.py @@ -69,16 +69,17 @@ class Room(object): if not msg: logger.info('msg is None..., %s' % (nick)) return - lines = msg.split('\n') + # lines = msg.split('\n') # first line has the nick and timestamp but others don't - self.lines.append((datetime.now(), nick.encode('utf-8'), lines.pop(0).encode('utf-8'))) - if len(lines) > 0: - for line in lines: - self.lines.append((line.encode('utf-8'))) + self.lines.append((datetime.now(), nick.encode('utf-8'), msg.encode('utf-8'))) + # if len(lines) > 0: + # for line in lines: + # self.lines.append((line.encode('utf-8'))) def add_info(self, info): """ info, like join/quit/status messages""" self.lines.append((datetime.now(), info.encode('utf-8'))) + return info.encode('utf-8') def on_presence(self, stanza, nick): """ @@ -89,26 +90,22 @@ class Room(object): role = stanza.getRole() if not self.joined: self.users.append(User(nick, affiliation, show, status, role)) - if nick == self.own_nick: + if nick.encode('utf-8') == self.own_nick.encode('utf-8'): self.joined = True - self.add_info("%s is in the room" % (nick)) - return + return self.add_info("%s is in the room" % (nick)) change_nick = stanza.getStatusCode() == '303' for user in self.users: - if user.nick == nick: + if user.nick.encode('utf-8') == nick.encode('utf-8'): if change_nick: user.change_nick(stanza.getNick()) - self.add_info('%s is now known as %s' % (nick, stanza.getNick())) - return + return self.add_info('%s is now known as %s' % (nick, stanza.getNick())) if status == 'offline' or role == 'none': self.users.remove(user) - self.add_info('%s has left the room' % (nick)) - return + return self.add_info('%s has left the room' % (nick)) user.update(affiliation, show, status, role) - self.add_info('%s, status : %s, %s, %s, %s' % (nick, affiliation, role, show, status)) - return + return self.add_info('%s, status : %s, %s, %s, %s' % (nick, affiliation, role, show, status)) self.users.append(User(nick, affiliation, show, status, role)) - self.add_info('%s joined the room %s' % (nick, self.name)) + return self.add_info('%s joined the room %s' % (nick, self.name)) class Gui(object): """ @@ -118,9 +115,10 @@ class Gui(object): self.init_curses(stdscr) self.stdscr = stdscr - self.stdscr.leaveok(True) + self.stdscr.leaveok(1) self.rooms = [Room('Info', '')] # current_room is self.rooms[0] self.window = Window(stdscr) + self.window.text_win.new_win('Info') self.window.refresh(self.rooms[0]) self.muc = muc @@ -162,20 +160,24 @@ class Gui(object): def reset_curses(self): curses.echo() + curses.endwin() def on_connected(self): pass def join_room(self, room, nick): + self.window.text_win.new_win(room) self.rooms.insert(0, Room(room, nick)) self.window.refresh(self.current_room()) def rotate_rooms_left(self, args): self.rooms.append(self.rooms.pop(0)) + self.stdscr.touchwin() self.window.refresh(self.current_room()) def rotate_rooms_right(self, args): self.rooms.insert(0, self.rooms.pop()) +# self.stdscr.touchwin() self.window.refresh(self.current_room()) def room_message(self, stanza): @@ -194,9 +196,9 @@ class Gui(object): room.add_info("%s changed the subject to: %s" % (nick_from, stanza.getSubject())) else: room.add_message(nick_from, body) + self.window.text_win.add_line(room, (datetime.now(), nick_from.encode('utf-8'), body.encode('utf-8'))) if room == self.current_room(): - self.window.text_win.refresh(room.lines, room.users) - self.window.user_win.refresh(room.users) + self.window.text_win.refresh(room.name) self.window.input.refresh() curses.doupdate() @@ -206,9 +208,10 @@ class Gui(object): room = self.get_room_by_name(from_room) if not room: return logger.warning("presence received for a non-existing room: %s" % (name)) - room.on_presence(stanza, from_nick) + msg = room.on_presence(stanza, from_nick) + self.window.text_win.add_line(room, (datetime.now(), msg)) if room == self.current_room(): - self.window.text_win.refresh(room.lines, room.users) + self.window.text_win.refresh(room.name) self.window.user_win.refresh(room.users) curses.doupdate() @@ -240,10 +243,24 @@ class Gui(object): def main_loop(self, stdscr): while 1: curses.doupdate() - key = stdscr.getch() - if key == curses.KEY_RESIZE: + key = stdscr.getkey() + if ord(key) == 195: + n = stdscr.getkey() + key = key+n + self.window.input.win.addstr(key) + self.window.input.add_char(key) + self.window.input.win.refresh() + elif ord(key) == 226: + n = stdscr.getkey() + m = stdscr.getkey() + key = key+n+m + self.window.input.win.addstr(key) + self.window.input.add_char(key) + self.window.input.win.refresh() + + elif key == curses.KEY_RESIZE: self.window.resize(stdscr) - elif key == 10: + elif ord(key) == 10: self.execute() else: - self.window.do_command(key) + self.window.do_command(ord(key)) diff --git a/src/poezio.cfg b/src/poezio.cfg index f453c946..1e517db5 100644 --- a/src/poezio.cfg +++ b/src/poezio.cfg @@ -3,5 +3,5 @@ logfile = logs resource = poezio server = louiz.org port = 5222 -rooms = discussion@kikoo.louiz.org/Poefion +rooms = discussion@kikoo.louiz.org/Poefion:test@chat.jabberfr.org/pd diff --git a/src/window.py b/src/window.py index e93da43b..5699151f 100644 --- a/src/window.py +++ b/src/window.py @@ -21,7 +21,7 @@ import curses from logging import logger def get_next_line(str, length): - pos = str.rfind(' ', 0, 30) + pos = str.rfind(' ', 0, length) if pos == -1: return str[:length], str[length:] else: @@ -45,6 +45,8 @@ class Win(object): self.win = parent_win.subwin(height, width, y, x) except: pass + def refresh(self): + self.win.noutrefresh() class UserList(Win): def __init__(self, height, width, y, x, parent_win): @@ -63,12 +65,15 @@ class UserList(Win): self.win.attroff(curses.color_pair(2)) y = 0 for user in users: - color = self.color_dict[user.role] + try: + color = self.color_dict[user.role] + except: + color = 1 self.win.attron(curses.color_pair(color)) self.win.addstr(y, 1, user.nick) self.win.attroff(curses.color_pair(color)) y += 1 - self.win.noutrefresh() + self.win.refresh() def resize(self, height, width, y, x, stdscr): self._resize(height, width, y, x, stdscr) @@ -84,48 +89,70 @@ class Info(Win): self.win.clear() self.win.addstr(0, 0, room_name + " "*(self.width-len(room_name)-1) , curses.color_pair(1)) - self.win.noutrefresh() + self.win.refresh() -class TextWin(Win): +class TextWin(object): + """ + 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) + """ def __init__(self, height, width, y, x, parent_win): - Win.__init__(self, height, width, y, x, parent_win) - self.win.idlok(True) - self.pos = 0 + self.height = height + self.width = width + self.y = y + self.x = x + self.parent_win = parent_win + self.wins = {} + + def rebuild(self, lines): + """ + called when the terminal is resized. + resize all the windows, clear them and rewrite + the lines in them + """ + pass # TODO - def refresh(self, lines, users): - self.win.clear() - y = 0 - # logger.info(str(self.height)) - # logger.info(str(lines[-self.height/2:])) - for line in lines[-self.height:]: # FIXME - if len(line) == 2: - try: - self.win.addstr(y, 0, '['+line[0].strftime("%H:%M:%S") + "] *" + line[1]+"*") - except: - logger.error(str(line)) - raise - y += 1 - elif len(line) == 3: - for user in users: - if user.nick == line[1]: - break - self.win.addstr(y, 0, '['+line[0].strftime("%H:%M:%S") + "] <") - length = len('['+line[0].strftime("%H:%M:%S") + "] <") - self.win.attron(curses.color_pair(user.color)) - self.win.addstr(y, length,line[1]) - self.win.attroff(curses.color_pair(user.color)) - self.win.addstr(y, length+len(line[1]), ">: ") - remaining_width = self.width-(length+len(line[1])+3) - tab = cut_line(line[2], remaining_width-1) - for l in tab: - try: - self.win.addstr(y, length+len(line[1])+3, l) - y += 1 - except:pass - elif len(line) == 1: - self.win.addstr(y, 0, line[0]) - y += 1 - self.win.noutrefresh() + def redraw(self, room): + """ + called when the buffer changes or is + resized (a complete redraw is needed) + """ + 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.wins[winname].refresh() + + def add_line(self, room, line): + win = self.wins[room.name].win + users = room.users + if len(line) == 2: + win.addstr('\n['+line[0].strftime("%H:%M:%S") + "] *" + line[1]+"*") + elif len(line) == 3: + for user in users: + if user.nick == line[1]: + break + win.addstr('\n['+line[0].strftime("%H:%M:%S") + "] <") + length = len('['+line[0].strftime("%H:%M:%S") + "] <") + win.attron(curses.color_pair(user.color)) + win.addstr(line[1]) + win.attroff(curses.color_pair(user.color)) + win.addstr("> ") + win.addstr(line[2]) + + 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) + self.wins[winname] = newwin def resize(self, height, width, y, x, stdscr): self._resize(height, width, y, x, stdscr) @@ -137,6 +164,8 @@ class Input(Win): Win.__init__(self, height, width, y, x, stdscr) self.input = curses.textpad.Textbox(self.win) self.input.insert_mode = True + self.win.keypad(True) + self.text = '' def resize(self, height, width, y, x, stdscr): self._resize(height, width, y, x, stdscr) @@ -144,16 +173,23 @@ class Input(Win): self.input.insert_mode = True self.win.clear() + def add_char(self, char): + self.text += char + def do_command(self, key): + self.text += chr(key) self.input.do_command(key) def get_text(self): - return self.input.gather() + txt = self.text + self.text = '' + return txt def save_text(self): self.txt = self.input.gather() def refresh(self): +# return self.win.noutrefresh() def clear_text(self): @@ -180,7 +216,6 @@ class Window(object): self.info_win = Info(1, self.width, self.height-2, 0, stdscr) self.text_win = TextWin(self.height-3, (self.width/7)*6, 1, 0, stdscr) self.input = Input(1, self.width, self.height-1, 0, stdscr) - # debug def resize(self, stdscr): """ @@ -194,7 +229,8 @@ class Window(object): self.input.resize(1, self.width, self.height-1, 0, stdscr) def refresh(self, room): - self.text_win.refresh(room.lines, room.users) + self.text_win.redraw(room) + self.text_win.refresh(room.name) self.user_win.refresh(room.users) self.topic_win.refresh(room.topic) self.info_win.refresh(room.name) -- cgit v1.2.3