Files reorganisation
This commit is contained in:
parent
c8b5f1db90
commit
e4452c4b03
1 changed files with 10 additions and 8 deletions
279
frontends/src/primitivus/chat.py
Normal file
279
frontends/src/primitivus/chat.py
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Primitivus: a SAT frontend
|
||||
Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import urwid
|
||||
from quick_frontend.quick_contact_list import QuickContactList
|
||||
from quick_frontend.quick_chat import QuickChat
|
||||
from urwid_satext import sat_widgets
|
||||
import time
|
||||
from tools.jid import JID
|
||||
from card_game import CardGame
|
||||
from urwid_satext.files_management import FileDialog
|
||||
|
||||
|
||||
class ChatText(urwid.FlowWidget):
|
||||
"""Manage the printing of chat message"""
|
||||
|
||||
def __init__(self, parent, timestamp, nick, my_mess, message, align='left'):
|
||||
self.parent = parent
|
||||
self.timestamp = time.localtime(timestamp)
|
||||
self.nick = nick
|
||||
self.my_mess = my_mess
|
||||
self.message = unicode(message)
|
||||
self.align = align
|
||||
|
||||
def selectable(self):
|
||||
return True
|
||||
|
||||
def keypress(self, size, key):
|
||||
return key
|
||||
|
||||
def rows(self,size,focus=False):
|
||||
return self.display_widget(size, focus).rows(size, focus)
|
||||
|
||||
def render(self, size, focus=False):
|
||||
canvas = urwid.CompositeCanvas(self.display_widget(size, focus).render(size, focus))
|
||||
if focus:
|
||||
canvas.set_cursor(self.get_cursor_coords(size))
|
||||
return canvas
|
||||
|
||||
def get_cursor_coords(self, size):
|
||||
#(maxcol,) = size
|
||||
return 0, 0
|
||||
|
||||
def display_widget(self, size, focus):
|
||||
render_txt = []
|
||||
if self.parent.show_timestamp:
|
||||
time_format = "%c" if self.timestamp < self.parent.day_change else "%H:%M" #if the message was sent before today, we print the full date
|
||||
render_txt.append(('date',"[%s]" % time.strftime(time_format, self.timestamp).decode('utf-8')))
|
||||
if self.parent.show_short_nick:
|
||||
render_txt.append(('my_nick' if self.my_mess else 'other_nick',"**" if self.my_mess else "*"))
|
||||
else:
|
||||
render_txt.append(('my_nick' if self.my_mess else 'other_nick',"[%s] " % self.nick))
|
||||
render_txt.append(self.message)
|
||||
return urwid.Text(render_txt, align=self.align)
|
||||
|
||||
class Chat(urwid.WidgetWrap, QuickChat):
|
||||
|
||||
def __init__(self, target, host, type='one2one'):
|
||||
self.target = target
|
||||
QuickChat.__init__(self, target, host, type)
|
||||
self.content = urwid.SimpleListWalker([])
|
||||
self.text_list = urwid.ListBox(self.content)
|
||||
self.chat_widget = urwid.Frame(self.text_list)
|
||||
self.chat_colums = urwid.Columns([('weight', 8, self.chat_widget)])
|
||||
self.chat_colums = urwid.Columns([('weight', 8, self.chat_widget)])
|
||||
self.pile = urwid.Pile([self.chat_colums])
|
||||
urwid.WidgetWrap.__init__(self, self.__getDecoration(self.pile))
|
||||
self.setType(type)
|
||||
self.day_change = time.strptime(time.strftime("%a %b %d 00:00:00 %Y")) #struct_time of day changing time
|
||||
self.show_timestamp = True
|
||||
self.show_short_nick = False
|
||||
self.show_title = 1 #0: clip title; 1: full title; 2: no title
|
||||
self.subject = None
|
||||
|
||||
def keypress(self, size, key):
|
||||
if key == "meta p": #user wants to (un)hide the presents panel
|
||||
if self.type == 'group':
|
||||
widgets = self.chat_colums.widget_list
|
||||
if self.present_panel in widgets:
|
||||
self.__removePresentPanel()
|
||||
else:
|
||||
self.__appendPresentPanel()
|
||||
elif key == "meta t": #user wants to (un)hide timestamp
|
||||
self.show_timestamp = not self.show_timestamp
|
||||
for wid in self.content:
|
||||
wid._invalidate()
|
||||
elif key == "meta n": #user wants to (not) use short nick
|
||||
self.show_short_nick = not self.show_short_nick
|
||||
for wid in self.content:
|
||||
wid._invalidate()
|
||||
elif key == "meta l": #user wants to (un)hide widget decoration
|
||||
show = not isinstance(self._w, sat_widgets.LabelLine)
|
||||
self.showDecoration(show)
|
||||
self._invalidate()
|
||||
elif key == "meta s": #user wants to (un)hide group's subject or change its apperance
|
||||
if self.subject:
|
||||
self.show_title = (self.show_title + 1) % 3
|
||||
if self.show_title == 0:
|
||||
self.setSubject(self.subject,'clip')
|
||||
elif self.show_title == 1:
|
||||
self.setSubject(self.subject,'space')
|
||||
elif self.show_title == 2:
|
||||
self.chat_widget.header = None
|
||||
self._invalidate()
|
||||
|
||||
|
||||
return super(Chat, self).keypress(size, key)
|
||||
|
||||
def getMenu(self):
|
||||
"""Return Menu bar"""
|
||||
menu = sat_widgets.Menu(self.host.loop)
|
||||
if self.type == 'group':
|
||||
game = _("Game")
|
||||
menu.addMenu(game, "Tarot", self.onTarotRequest)
|
||||
elif self.type == 'one2one':
|
||||
menu.addMenu(_("Action"), _("Send file"), self.onSendFileRequest)
|
||||
return menu
|
||||
|
||||
def setType(self, type):
|
||||
QuickChat.setType(self, type)
|
||||
if type == 'one2one':
|
||||
self.historyPrint(profile=self.host.profile)
|
||||
elif type == 'group':
|
||||
if len(self.chat_colums.widget_list) == 1:
|
||||
present_widget = self.__buildPresentList()
|
||||
self.present_panel = sat_widgets.VerticalSeparator(present_widget)
|
||||
self.__appendPresentPanel()
|
||||
|
||||
def __getDecoration(self, widget):
|
||||
return sat_widgets.LabelLine(widget, sat_widgets.SurroundedText(unicode(self.target)))
|
||||
|
||||
def showDecoration(self, show=True):
|
||||
"""Show/Hide the decoration around the chat window"""
|
||||
if show:
|
||||
main_widget = self.__getDecoration(self.pile)
|
||||
else:
|
||||
main_widget = self.pile
|
||||
self._w = main_widget
|
||||
|
||||
|
||||
def __buildPresentList(self):
|
||||
self.present_wid = sat_widgets.GenericList([],option_type = sat_widgets.ClickableText)
|
||||
return self.present_wid
|
||||
|
||||
def __appendPresentPanel(self):
|
||||
self.chat_colums.widget_list.append(self.present_panel)
|
||||
self.chat_colums.column_types.append(('weight', 2))
|
||||
|
||||
def __removePresentPanel(self):
|
||||
self.chat_colums.set_focus(0) #necessary as the focus change to the next object, we can go out of range if we are on the last object of self.chat_colums
|
||||
self.chat_colums.widget_list.remove(self.present_panel)
|
||||
del self.chat_colums.column_types[-1]
|
||||
|
||||
def __appendGamePanel(self, widget):
|
||||
assert (len(self.pile.widget_list) == 1)
|
||||
self.pile.widget_list.insert(0,widget)
|
||||
self.pile.item_types.insert(0,('weight', 1))
|
||||
self.pile.widget_list.insert(1,urwid.Filler(urwid.Divider('-')))
|
||||
self.pile.item_types.insert(1,('fixed', 1))
|
||||
self.host.redraw()
|
||||
|
||||
def __removeGamePanel(self):
|
||||
assert (len(self.pile.widget_list) == 3)
|
||||
self.pile.set_focus(0) #necessary as the focus change to the next object, we can go out of range if we are on the last object of self.chat_colums
|
||||
del self.pile.widget_list[0]
|
||||
del self.pile.item_types[0]
|
||||
self.host.redraw()
|
||||
|
||||
def setSubject(self, subject, wrap='space'):
|
||||
"""Set title for a group chat"""
|
||||
QuickChat.setSubject(self, subject)
|
||||
self.subject = subject
|
||||
self.subj_wid = urwid.Text(unicode(subject.replace('\n','|') if wrap == 'clip' else subject ),
|
||||
align='left' if wrap=='clip' else 'center',wrap=wrap)
|
||||
self.chat_widget.header = urwid.AttrMap(self.subj_wid,'title')
|
||||
self.host.redraw()
|
||||
|
||||
def setPresents(self, param_nicks):
|
||||
"""Set the users presents in the contact list for a group chat
|
||||
@param nicks: list of nicknames
|
||||
"""
|
||||
nicks = [unicode(nick) for nick in param_nicks] #FIXME: should be done in DBus bridge
|
||||
nicks.sort()
|
||||
QuickChat.setPresents(self, nicks)
|
||||
self.present_wid.changeValues(nicks)
|
||||
self.host.redraw()
|
||||
|
||||
def replaceUser(self, param_nick):
|
||||
"""Add user if it is not in the group list"""
|
||||
nick = unicode(param_nick) #FIXME: should be done in DBus bridge
|
||||
if "facebook" in nick:
|
||||
self.host.debug()
|
||||
QuickChat.replaceUser(self, nick)
|
||||
presents = self.present_wid.getAllValues()
|
||||
if nick not in presents:
|
||||
presents.append(nick)
|
||||
presents.sort()
|
||||
self.present_wid.changeValues(presents)
|
||||
self.host.redraw()
|
||||
|
||||
def removeUser(self, param_nick):
|
||||
"""Remove a user from the group list"""
|
||||
nick = unicode(param_nick) #FIXME: should be done in DBus bridge
|
||||
QuickChat.removeUser(self, nick)
|
||||
self.present_wid.deleteValue(nick)
|
||||
self.host.redraw()
|
||||
|
||||
def printMessage(self, from_jid, msg, profile, timestamp=""):
|
||||
assert isinstance(from_jid, JID)
|
||||
try:
|
||||
jid,nick,mymess = QuickChat.printMessage(self, from_jid, msg, profile, timestamp)
|
||||
except TypeError:
|
||||
return
|
||||
my_jid = self.host.profiles[profile]['whoami']
|
||||
self.content.append(ChatText(self, timestamp or None, nick, mymess, msg))
|
||||
self.text_list.set_focus(len(self.content)-1)
|
||||
self.host.redraw()
|
||||
|
||||
def printInfo(self, msg, type='normal'):
|
||||
"""Print general info
|
||||
@param msg: message to print
|
||||
@type: one of:
|
||||
normal: general info like "toto has joined the room"
|
||||
me: "/me" information like "/me clenches his fist" ==> "toto clenches his fist"
|
||||
"""
|
||||
self.content.append(sat_widgets.ClickableText(msg))
|
||||
self.text_list.set_focus(len(self.content)-1)
|
||||
self.host.redraw()
|
||||
|
||||
def startGame(self, game_type, referee, players):
|
||||
"""Configure the chat window to start a game"""
|
||||
if game_type=="Tarot":
|
||||
try:
|
||||
self.tarot_wid = CardGame(self, referee, players, self.nick)
|
||||
self.__appendGamePanel(self.tarot_wid)
|
||||
except e:
|
||||
self.host.debug()
|
||||
|
||||
def getGame(self, game_type):
|
||||
"""Return class managing the game type"""
|
||||
#TODO: check that the game is launched, and manage errors
|
||||
if game_type=="Tarot":
|
||||
return self.tarot_wid
|
||||
|
||||
#MENU EVENTS#
|
||||
def onTarotRequest(self, menu):
|
||||
if len(self.occupants) != 4:
|
||||
self.host.showPopUp(sat_widgets.Alert(_("Can't start game"), _("You need to be exactly 4 peoples in the room to start a Tarot game"), ok_cb=self.host.removePopUp))
|
||||
else:
|
||||
self.host.bridge.tarotGameCreate(self.id, list(self.occupants), self.host.profile)
|
||||
|
||||
def onSendFileRequest(self, menu):
|
||||
dialog = FileDialog(ok_cb=self.onFileSelected, cancel_cb=self.host.removePopUp)
|
||||
self.host.showPopUp(dialog, 80, 80)
|
||||
|
||||
#MISC EVENTS#
|
||||
def onFileSelected(self, filepath):
|
||||
self.host.removePopUp()
|
||||
full_jid = self.host.CM.get_full(self.target)
|
||||
id = self.host.bridge.sendFile(full_jid, filepath)
|
||||
self.host.addProgress(id,filepath)
|
||||
Loading…
Reference in a new issue