Mercurial > libervia-backend
comparison frontends/src/wix/chat.py @ 223:86d249b6d9b7
Files reorganisation
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 29 Dec 2010 01:06:29 +0100 |
parents | frontends/wix/chat.py@31632472e857 |
children | fd9b7834d98a |
comparison
equal
deleted
inserted
replaced
222:3198bfd66daa | 223:86d249b6d9b7 |
---|---|
1 #!/usr/bin/python | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 wix: a SAT frontend | |
6 Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org) | |
7 | |
8 This program is free software: you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation, either version 3 of the License, or | |
11 (at your option) any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 """ | |
21 | |
22 | |
23 | |
24 import wx | |
25 import os.path | |
26 import time | |
27 import pdb | |
28 from logging import debug, info, error, warning | |
29 from tools.jid import JID | |
30 from quick_frontend.quick_chat import QuickChat | |
31 from contact_list import ContactList | |
32 from card_game import CardPanel | |
33 | |
34 | |
35 idSEND = 1 | |
36 idTAROT = 2 | |
37 | |
38 class Chat(wx.Frame, QuickChat): | |
39 """The chat Window for one to one conversations""" | |
40 | |
41 def __init__(self, target, host, type='one2one'): | |
42 wx.Frame.__init__(self, None, title=target, pos=(0,0), size=(400,200)) | |
43 QuickChat.__init__(self, target, host, type) | |
44 | |
45 self.sizer = wx.BoxSizer(wx.VERTICAL) | |
46 self.SetSizer(self.sizer) | |
47 | |
48 self.splitter = wx.SplitterWindow(self, -1) | |
49 self.sizer.Add(self.splitter, 1, flag = wx.EXPAND) | |
50 | |
51 self.conv_panel = wx.Panel(self.splitter) | |
52 self.conv_panel.sizer = wx.BoxSizer(wx.VERTICAL) | |
53 self.subjectBox = wx.TextCtrl(self.conv_panel, -1, style = wx.TE_READONLY) | |
54 self.chatWindow = wx.TextCtrl(self.conv_panel, -1, style = wx.TE_MULTILINE | wx.TE_RICH | wx.TE_READONLY) | |
55 self.textBox = wx.TextCtrl(self.conv_panel, -1, style = wx.TE_PROCESS_ENTER) | |
56 self.conv_panel.sizer.Add(self.subjectBox, flag=wx.EXPAND) | |
57 self.conv_panel.sizer.Add(self.chatWindow, 1, flag=wx.EXPAND) | |
58 self.conv_panel.sizer.Add(self.textBox, 0, flag=wx.EXPAND) | |
59 self.conv_panel.SetSizer(self.conv_panel.sizer) | |
60 self.splitter.Initialize(self.conv_panel) | |
61 self.SetMenuBar(wx.MenuBar()) | |
62 | |
63 #events | |
64 self.Bind(wx.EVT_CLOSE, self.onClose, self) | |
65 self.Bind(wx.EVT_TEXT_ENTER, self.onEnterPressed, self.textBox) | |
66 | |
67 #fonts | |
68 self.font={} | |
69 self.font["points"] = self.chatWindow.GetFont().GetPointSize() | |
70 self.font["family"] = self.chatWindow.GetFont().GetFamily() | |
71 | |
72 | |
73 #misc | |
74 self.day_change = time.strptime(time.strftime("%a %b %d 00:00:00 %Y")) #struct_time of day changing time | |
75 self.setType(self.type) | |
76 self.textBox.SetFocus() | |
77 self.Hide() #We hide because of the show toggle | |
78 | |
79 def __createPresents(self): | |
80 """Create a list of present people in a group chat""" | |
81 self.present_panel = wx.Panel(self.splitter) | |
82 self.present_panel.sizer = wx.BoxSizer(wx.VERTICAL) | |
83 self.present_panel.SetBackgroundColour(wx.BLUE) | |
84 self.present_panel.presents = ContactList(self.present_panel, self.host, type='nicks') | |
85 self.present_panel.presents.SetMinSize(wx.Size(80,20)) | |
86 self.present_panel.sizer.Add(self.present_panel.presents, 1, wx.EXPAND) | |
87 self.present_panel.SetSizer(self.present_panel.sizer) | |
88 self.splitter.SplitVertically(self.present_panel, self.conv_panel, 80) | |
89 | |
90 def setType(self, type): | |
91 QuickChat.setType(self, type) | |
92 if type is 'group' and not self.splitter.IsSplit(): | |
93 self.__createPresents() | |
94 self.subjectBox.Show() | |
95 self.__eraseMenus() | |
96 self.__createMenus_group() | |
97 self.sizer.Layout() | |
98 elif type is 'one2one' and self.splitter.IsSplit(): | |
99 self.splitter.Unsplit(self.present_panel) | |
100 del self.present_panel | |
101 self.GetMenuBar().Show() | |
102 self.subjectBox.Hide() | |
103 self.__eraseMenus() | |
104 self.__createMenus_O2O() | |
105 self.nick = None | |
106 else: | |
107 self.subjectBox.Hide() | |
108 self.__eraseMenus() | |
109 self.__createMenus_O2O() | |
110 self.historyPrint(profile=self.host.profile) | |
111 | |
112 def startGame(self, game_type, referee, players): | |
113 """Configure the chat window to start a game""" | |
114 if game_type=="Tarot": | |
115 debug (_("configure chat window for Tarot game")) | |
116 self.tarot_panel = CardPanel(self, referee, players, self.nick) | |
117 self.sizer.Prepend(self.tarot_panel, 0, flag=wx.EXPAND) | |
118 self.sizer.Layout() | |
119 self.Fit() | |
120 | |
121 def getGame(self, game_type): | |
122 """Return class managing the game type""" | |
123 #TODO: check that the game is launched, and manage errors | |
124 if game_type=="Tarot": | |
125 return self.tarot_panel | |
126 | |
127 | |
128 def setPresents(self, nicks): | |
129 """Set the users presents in the contact list for a group chat | |
130 @param nicks: list of nicknames | |
131 """ | |
132 QuickChat.setPresents(self, nicks) | |
133 for nick in nicks: | |
134 self.present_panel.presents.replace(nick) | |
135 | |
136 def replaceUser(self, nick): | |
137 """Add user if it is not in the group list""" | |
138 debug (_("Replacing user %s") % nick) | |
139 if self.type != "group": | |
140 error (_("[INTERNAL] trying to replace user for a non group chat window")) | |
141 return | |
142 QuickChat.replaceUser(self, nick) | |
143 self.present_panel.presents.replace(nick) | |
144 | |
145 def removeUser(self, nick): | |
146 """Remove a user from the group list""" | |
147 QuickChat.removeUser(self, nick) | |
148 self.present_panel.presents.remove(nick) | |
149 | |
150 def setSubject(self, subject): | |
151 """Set title for a group chat""" | |
152 QuickChat.setSubject(self, subject) | |
153 self.subjectBox.SetValue(subject) | |
154 | |
155 def __eraseMenus(self): | |
156 """erase all menus""" | |
157 menuBar = self.GetMenuBar() | |
158 for i in range(menuBar.GetMenuCount()): | |
159 menuBar.Remove(i) | |
160 | |
161 def __createMenus_O2O(self): | |
162 """create menu bar for one 2 one chat""" | |
163 info("Creating menus") | |
164 self.__eraseMenus() | |
165 menuBar = self.GetMenuBar() | |
166 actionMenu = wx.Menu() | |
167 actionMenu.Append(idSEND, _("&SendFile CTRL-s"),_(" Send a file to contact")) | |
168 menuBar.Append(actionMenu,_("&Action")) | |
169 | |
170 #events | |
171 wx.EVT_MENU(self, idSEND, self.onSendFile) | |
172 | |
173 def __createMenus_group(self): | |
174 """create menu bar for group chat""" | |
175 info("Creating menus") | |
176 self.__eraseMenus() | |
177 menuBar = self.GetMenuBar() | |
178 actionMenu = wx.Menu() | |
179 actionMenu.Append(idTAROT, _("Start &Tarot game CTRL-t"),_(" Start a Tarot card game")) #tmp | |
180 menuBar.Append(actionMenu,_("&Games")) | |
181 | |
182 #events | |
183 wx.EVT_MENU(self, idTAROT, self.onStartTarot) | |
184 | |
185 def __del__(self): | |
186 wx.Frame.__del__(self) | |
187 | |
188 def onClose(self, event): | |
189 """Close event: we only hide the frame.""" | |
190 event.Veto() | |
191 self.Hide() | |
192 | |
193 def onEnterPressed(self, event): | |
194 """Behaviour when enter pressed in send line.""" | |
195 self.host.bridge.sendMessage(self.target.short if self.type=='group' else self.target, | |
196 event.GetString(), | |
197 type = "groupchat" if self.type=='group' else "chat", | |
198 profile_key=self.host.profile) | |
199 self.textBox.Clear() | |
200 | |
201 def __blink(self): | |
202 """Do wizzz and buzzz to show window to user or | |
203 at least inform him of something new""" | |
204 #TODO: use notification system | |
205 if not self.IsActive(): | |
206 self.RequestUserAttention() | |
207 if not self.IsShown(): | |
208 self.Show() | |
209 | |
210 def printMessage(self, from_jid, msg, profile, timestamp=""): | |
211 """Print the message with differents colors depending on where it comes from.""" | |
212 try: | |
213 jid,nick,mymess = QuickChat.printMessage(self, from_jid, msg, profile, timestamp) | |
214 except TypeError: | |
215 return | |
216 print "printMessage, jid=",jid,"type=",self.type | |
217 _font_bold = wx.Font(self.font["points"], self.font["family"], wx.NORMAL, wx.BOLD) | |
218 _font_normal = wx.Font(self.font["points"], self.font["family"], wx.NORMAL, wx.NORMAL) | |
219 _font_italic = wx.Font(self.font["points"], self.font["family"], wx.ITALIC if mymess else wx.NORMAL, wx.NORMAL) | |
220 self.chatWindow.SetDefaultStyle(wx.TextAttr("GREY", font=_font_normal)) | |
221 msg_time = time.localtime(timestamp or None) | |
222 time_format = "%c" if msg_time < self.day_change else "%H:%M" #if the message was sent before today, we print the full date | |
223 self.chatWindow.AppendText("[%s]" % time.strftime(time_format, msg_time )) | |
224 self.chatWindow.SetDefaultStyle(wx.TextAttr( "BLACK" if mymess else "BLUE", font=_font_bold)) | |
225 self.chatWindow.AppendText("[%s] " % nick) | |
226 self.chatWindow.SetDefaultStyle(wx.TextAttr("BLACK", font=_font_italic)) | |
227 self.chatWindow.AppendText("%s\n" % msg) | |
228 if not mymess: | |
229 self.__blink() | |
230 | |
231 def printInfo(self, msg, type='normal'): | |
232 """Print general info | |
233 @param msg: message to print | |
234 @type: one of: | |
235 normal: general info like "toto has joined the room" | |
236 me: "/me" information like "/me clenches his fist" ==> "toto clenches his fist" | |
237 """ | |
238 _font_bold = wx.Font(self.font["points"], self.font["family"], wx.NORMAL, wx.BOLD) | |
239 _font_normal = wx.Font(self.font["points"], self.font["family"], wx.NORMAL, wx.NORMAL) | |
240 self.chatWindow.SetDefaultStyle(wx.TextAttr("BLACK", font=_font_bold if type == 'normal' else _font_normal)) | |
241 self.chatWindow.AppendText("%s\n" % msg) | |
242 if type=="me": | |
243 self.__blink() | |
244 | |
245 ### events ### | |
246 | |
247 def onSendFile(self, e): | |
248 debug(_("Send File")) | |
249 filename = wx.FileSelector(_("Choose a file to send"), flags = wx.FD_FILE_MUST_EXIST) | |
250 if filename: | |
251 debug(_("filename: %s"),filename) | |
252 full_jid = self.host.CM.get_full(self.target) | |
253 id = self.host.bridge.sendFile(full_jid, filename) | |
254 self.host.waitProgress(id, _("File Transfer"), _("Copying %s") % os.path.basename(filename)) | |
255 | |
256 def onStartTarot(self, e): | |
257 debug (_("Starting Tarot game")) | |
258 warning (_("FIXME: temporary menu, must be changed")) | |
259 if len(self.occupants) != 4: | |
260 err_dlg = wx.MessageDialog(self, _("You need to be exactly 4 peoples in the room to start a Tarot game"), _("Can't start game"), style = wx.OK | wx.ICON_ERROR) #FIXME: gof: temporary only, need to choose the people with who the game has to be started | |
261 err_dlg.ShowModal() | |
262 else: | |
263 self.host.bridge.tarotGameCreate(self.id, list(self.occupants), self.host.profile) |