From c638055b244780fd7c3700165aace9b6bfceae92 Mon Sep 17 00:00:00 2001 From: "louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13" Date: Thu, 11 Feb 2010 04:59:58 +0000 Subject: [PATCH] fixed #1148 --- src/client.py | 8 ++--- src/connection.py | 6 ++-- src/gui.py | 77 +++++++++++++++++++++++++++++------------------ src/window.py | 50 +++++++++++++++++++++++++++--- 4 files changed, 99 insertions(+), 42 deletions(-) diff --git a/src/client.py b/src/client.py index f64dc5e6..9840d259 100644 --- a/src/client.py +++ b/src/client.py @@ -19,9 +19,9 @@ import sys # disable any printout (this would mess the display) -STDERR = sys.stderr -sys.stderr = open('/dev/null', 'w') +stderr = sys.stderr sys.stdout = open('/dev/null', 'w') +sys.stderr = open('/dev/null', 'w') from connection import Connection from multiuserchat import MultiUserChat @@ -43,7 +43,7 @@ def exception_handler(type_, value, trace): """ curses.echo() curses.endwin() - traceback.print_exception(type_, value, trace, None, STDERR) + traceback.print_exception(type_, value, trace, None, stderr) sys.exit() sys.excepthook = exception_handler @@ -59,8 +59,8 @@ class Client(object): self.resource = config.get('resource', 'poezio') self.server = config.get('server', 'louiz.org') self.connection = Connection(self.server, self.resource) - self.stdscr = initscr() + self.connection.start() self.gui = Gui(self.stdscr, MultiUserChat(self.connection.client)) diff --git a/src/connection.py b/src/connection.py index c651032e..8a042502 100644 --- a/src/connection.py +++ b/src/connection.py @@ -22,16 +22,16 @@ import sys import xmpp from config import config from logging import logger -from threading import Thread from handler import Handler +import threading -class Connection(Thread): +class Connection(threading.Thread): """ Receives everything from Jabber and emits the appropriate signals """ def __init__(self, server, resource): - Thread.__init__(self) + threading.Thread.__init__(self) self.handler = Handler() self.server = server diff --git a/src/gui.py b/src/gui.py index d610435f..f6f0a5e2 100644 --- a/src/gui.py +++ b/src/gui.py @@ -58,9 +58,11 @@ class User(object): class Room(object): """ """ - def __init__(self, name, nick): + def __init__(self, name, nick, number): self.name = name self.own_nick = nick + self.color_state = 11 # color used in RoomInfo + self.nb = number # number used in RoomInfo self.joined = False # false until self presence is received self.users = [] self.lines = [] # (time, nick, msg) or (time, info) @@ -71,6 +73,8 @@ class Room(object): self.users = [] def add_message(self, nick, msg): + self.set_color_state(12) + # TODO check for highlight if not msg: logger.info('msg is None..., %s' % (nick)) return @@ -92,6 +96,9 @@ class Room(object): return user return None + def set_color_state(self, color): + self.color_state = color + def on_presence(self, stanza, nick): """ """ @@ -151,13 +158,14 @@ class Gui(object): Graphical 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', '')] # current_room is self.rooms[0] + self.rooms = [Room('Info', '', self.next_room_number())] # current_room is self.rooms[0] self.window = Window(stdscr) - self.window.text_win.new_win('Info') - self.window.refresh(self.rooms[0]) + self.window.new_room(self.current_room()) + self.window.refresh(self.rooms) + self.muc = muc @@ -210,13 +218,13 @@ class Gui(object): key = stdscr.getkey() except: self.window.resize(stdscr) - self.window.refresh(self.current_room()) + self.window.refresh(self.rooms) continue if str(key) in self.key_func.keys(): self.key_func[key]() elif str(key) == 'KEY_RESIZE': self.window.resize(stdscr) - self.window.refresh(self.current_room()) + self.window.refresh(self.rooms) elif len(key) >= 4: continue elif ord(key) == 10: @@ -238,6 +246,11 @@ class Gui(object): key = key+stdscr.getkey() self.window.do_command(key) + def next_room_number(self): + nb = self.room_number + self.room_number += 1 + return nb + def current_room(self): return self.rooms[0] @@ -260,6 +273,10 @@ class Gui(object): curses.init_pair(7, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(8, curses.COLOR_MAGENTA, curses.COLOR_BLACK) curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK) + curses.init_pair(10, curses.COLOR_WHITE, curses.COLOR_GREEN) # current room + curses.init_pair(11, curses.COLOR_WHITE, curses.COLOR_BLUE) # normal room + curses.init_pair(12, curses.COLOR_WHITE, curses.COLOR_CYAN) # new message room + curses.init_pair(13, curses.COLOR_WHITE, curses.COLOR_RED) # highlight room def reset_curses(self): curses.echo() @@ -270,17 +287,29 @@ class Gui(object): self.information(_("Your JID is %s") % jid) 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=None): - self.rooms.append(self.rooms.pop(0)) - self.window.refresh(self.current_room()) + r = Room(room, nick, self.next_room_number()) + self.current_room().set_color_state(11) + if self.current_room().nb == 0: + self.rooms.append(r) + else: + for ro in self.rooms: + if ro.nb == 0: + self.rooms.insert(self.rooms.index(ro), r) + break + while self.current_room().nb != r.nb: + self.rooms.insert(0, self.rooms.pop()) + self.window.new_room(r) + self.window.refresh(self.rooms) def rotate_rooms_right(self, args=None): + self.current_room().set_color_state(11) + self.rooms.append(self.rooms.pop(0)) + self.window.refresh(self.rooms) + + def rotate_rooms_left(self, args=None): + self.current_room().set_color_state(11) self.rooms.insert(0, self.rooms.pop()) - self.window.refresh(self.current_room()) + self.window.refresh(self.rooms) def room_message(self, stanza): if len(sys.argv) > 1: @@ -311,6 +340,8 @@ class Gui(object): if room == self.current_room(): self.window.text_win.refresh(room.name) self.window.input.refresh() + else: + self.window.info_win.refresh(self.rooms, self.current_room()) curses.doupdate() def room_presence(self, stanza): @@ -385,20 +416,6 @@ class Gui(object): roomname = self.current_room().name self.muc.eject_user(roomname, 'kick', nick, reason) - # def command_ban(self, args): - # if len(args) < 1: - # self.command_help(['ban']) - # return - # nick = args[0] - # if len(args) >= 2: - # reason = ' '.join(args[1:]) - # else: - # reason = None - # if self.current_room().name == 'Info' or not self.current_room().joined: - # return - # roomname = self.current_room().name - # self.muc.eject_user(roomname, 'ban', nick, reason) - def command_join(self, args): if len(args) == 0: r = self.current_room() @@ -512,7 +529,7 @@ class Gui(object): if room.joined: self.muc.quit_room(room.name, room.own_nick, msg) self.rooms.remove(self.current_room()) - self.window.refresh(self.current_room()) + self.window.refresh(self.rooms) def command_nick(self, args): if len(args) != 1: diff --git a/src/window.py b/src/window.py index 8aa95995..857d441e 100644 --- a/src/window.py +++ b/src/window.py @@ -65,7 +65,7 @@ class UserList(Win): return self._resize(height, width, y, x, stdscr) -class Info(Win): +class Topic(Win): def __init__(self, height, width, y, x, parent_win, visible): self.visible = visible Win.__init__(self, height, width, y, x, parent_win) @@ -83,6 +83,40 @@ class Info(Win): except:pass self.win.refresh() +class RoomInfo(Win): + def __init__(self, height, width, y, x, parent_win, visible): + self.visible = visible + Win.__init__(self, height, width, y, x, parent_win) + + def resize(self, height, width, y, x, stdscr, visible): + self._resize(height, width, y, x, stdscr) + + def refresh(self, rooms, current): + if not self.visible: + return + def compare_room(a, b): + return a.nb - b.nb + self.win.clear() + self.win.addnstr(0, 0, current.name+" [", self.width-1 + ,curses.color_pair(1)) + sorted_rooms = sorted(rooms, compare_room) + for room in sorted_rooms: + if current == room: + color = 10 + else: + color = room.color_state + try: + self.win.addstr(str(room.nb), curses.color_pair(color)) + self.win.addstr(",", curses.color_pair(1)) + except: # end of line + break + (y, x) = self.win.getyx() + try: + self.win.addstr(y, x-1, ']'+(' '*((self.width-1)-x)), curses.color_pair(1)) + except: + pass + self.win.refresh() + class TextWin(object): """ keep a dict of {winname: window} @@ -341,8 +375,8 @@ class Window(object): stdscr.vline(1, 9*(self.width/10), curses.ACS_VLINE, self.height-2) stdscr.attroff(curses.color_pair(2)) self.user_win = UserList(self.height-3, (self.width/10)-1, 1, 9*(self.width/10)+1, stdscr, visible) - self.topic_win = Info(1, self.width, 0, 0, stdscr, visible) - self.info_win = Info(1, self.width, self.height-2, 0, stdscr, visible) + self.topic_win = Topic(1, self.width, 0, 0, stdscr, visible) + self.info_win = RoomInfo(1, self.width, self.height-2, 0, stdscr, visible) self.text_win = TextWin(self.height-3, (self.width/10)*9, 1, 0, stdscr, visible) self.input = Input(1, self.width, self.height-1, 0, stdscr, visible) @@ -365,15 +399,21 @@ class Window(object): self.text_win.resize(self.height-3, (self.width/10)*9, 1, 0, stdscr, visible) self.input.resize(1, self.width, self.height-1, 0, stdscr, visible) - def refresh(self, room): + def refresh(self, rooms): + """ + 'room' is the current one + """ + room = rooms[0] # get current room 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) + self.info_win.refresh(rooms, room) self.input.refresh() def do_command(self, key): self.input.do_command(key) self.input.refresh() + def new_room(self, room): + self.text_win.new_win(room.name)