annotate frontends/sortilege/sortilege @ 51:8c67ea98ab91

frontend improved to take into account new SàT features - quick_frontend: better use of contact management, it now manages nicks, avatars, and connected status - quick_frontend: disconnect and remove are now 2 separate methods for contact list - wix: new contact list using HTML items, and showing avatars. Groups are not showed for now - wix: contact status now use tuples, to keep order, human readable status and color of contact - wix: contact list is updated when avatar or nick is found - wix: fixed 'question' dialog, which is renamed in 'yes/no' - wix: action result are now ignored for unkwnown id - sortilege refactored to work again
author Goffi <goffi@goffi.org>
date Thu, 07 Jan 2010 00:17:27 +1100
parents c4badbf3dd97
children 6455fb62ff83
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
goffi@necton2
parents:
diff changeset
1 #!/usr/bin/python
goffi@necton2
parents:
diff changeset
2 # -*- coding: utf-8 -*-
goffi@necton2
parents:
diff changeset
3
goffi@necton2
parents:
diff changeset
4 """
goffi@necton2
parents:
diff changeset
5 sortilege: a SAT frontend
goffi@necton2
parents:
diff changeset
6 Copyright (C) 2009 Jérôme Poisson (goffi@goffi.org)
goffi@necton2
parents:
diff changeset
7
goffi@necton2
parents:
diff changeset
8 This program is free software: you can redistribute it and/or modify
goffi@necton2
parents:
diff changeset
9 it under the terms of the GNU General Public License as published by
goffi@necton2
parents:
diff changeset
10 the Free Software Foundation, either version 3 of the License, or
goffi@necton2
parents:
diff changeset
11 (at your option) any later version.
goffi@necton2
parents:
diff changeset
12
goffi@necton2
parents:
diff changeset
13 This program is distributed in the hope that it will be useful,
goffi@necton2
parents:
diff changeset
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
goffi@necton2
parents:
diff changeset
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
goffi@necton2
parents:
diff changeset
16 GNU General Public License for more details.
goffi@necton2
parents:
diff changeset
17
goffi@necton2
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
goffi@necton2
parents:
diff changeset
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
goffi@necton2
parents:
diff changeset
20 """
goffi@necton2
parents:
diff changeset
21
goffi@necton2
parents:
diff changeset
22
goffi@necton2
parents:
diff changeset
23 import curses
goffi@necton2
parents:
diff changeset
24 import pdb
goffi@necton2
parents:
diff changeset
25 from window import Window
goffi@necton2
parents:
diff changeset
26 from editbox import EditBox
goffi@necton2
parents:
diff changeset
27 from statusbar import StatusBar
goffi@necton2
parents:
diff changeset
28 from chat import Chat
goffi@necton2
parents:
diff changeset
29 from tools.jid import JID
goffi@necton2
parents:
diff changeset
30 import logging
goffi@necton2
parents:
diff changeset
31 from logging import debug, info, error
goffi@necton2
parents:
diff changeset
32 import locale
goffi@necton2
parents:
diff changeset
33 import sys, os
goffi@necton2
parents:
diff changeset
34 import gobject
goffi@necton2
parents:
diff changeset
35 import time
goffi@necton2
parents:
diff changeset
36 from curses import ascii
goffi@necton2
parents:
diff changeset
37 import locale
goffi@necton2
parents:
diff changeset
38 from signal import signal, SIGWINCH
goffi@necton2
parents:
diff changeset
39 import fcntl
goffi@necton2
parents:
diff changeset
40 import struct
goffi@necton2
parents:
diff changeset
41 import termios
goffi@necton2
parents:
diff changeset
42 from boxsizer import BoxSizer
goffi@necton2
parents:
diff changeset
43 from quick_frontend.quick_chat_list import QuickChatList
goffi@necton2
parents:
diff changeset
44 from quick_frontend.quick_contact_list import QuickContactList
goffi@necton2
parents:
diff changeset
45 from quick_frontend.quick_app import QuickApp
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
46 from quick_frontend.quick_contact_management import QuickContactManagement
0
goffi@necton2
parents:
diff changeset
47
goffi@necton2
parents:
diff changeset
48 ### logging configuration FIXME: put this elsewhere ###
goffi@necton2
parents:
diff changeset
49 logging.basicConfig(level=logging.CRITICAL, #TODO: configure it top put messages in a log file
goffi@necton2
parents:
diff changeset
50 format='%(message)s')
goffi@necton2
parents:
diff changeset
51 ###
goffi@necton2
parents:
diff changeset
52
goffi@necton2
parents:
diff changeset
53 const_APP_NAME = "Sortilège"
goffi@necton2
parents:
diff changeset
54 const_CONTACT_WIDTH = 30
goffi@necton2
parents:
diff changeset
55
goffi@necton2
parents:
diff changeset
56 def ttysize():
goffi@necton2
parents:
diff changeset
57 """This function return term size.
goffi@necton2
parents:
diff changeset
58 Comes from Donn Cave from python list mailing list"""
goffi@necton2
parents:
diff changeset
59 buf = 'abcdefgh'
goffi@necton2
parents:
diff changeset
60 buf = fcntl.ioctl(0, termios.TIOCGWINSZ, buf)
goffi@necton2
parents:
diff changeset
61 row, col, rpx, cpx = struct.unpack('hhhh', buf)
goffi@necton2
parents:
diff changeset
62 return row, col
goffi@necton2
parents:
diff changeset
63
goffi@necton2
parents:
diff changeset
64 def C(k):
goffi@necton2
parents:
diff changeset
65 """return the value of Ctrl+key"""
goffi@necton2
parents:
diff changeset
66 return ord(ascii.ctrl(k))
goffi@necton2
parents:
diff changeset
67
goffi@necton2
parents:
diff changeset
68 class ChatList(QuickChatList):
goffi@necton2
parents:
diff changeset
69 """This class manage the list of chat windows"""
goffi@necton2
parents:
diff changeset
70
goffi@necton2
parents:
diff changeset
71 def __init__(self, host):
goffi@necton2
parents:
diff changeset
72 QuickChatList.__init__(self, host)
goffi@necton2
parents:
diff changeset
73 self.sizer=host.sizer
goffi@necton2
parents:
diff changeset
74
goffi@necton2
parents:
diff changeset
75 def createChat(self, name):
goffi@necton2
parents:
diff changeset
76 chat = Chat(name, self.host)
goffi@necton2
parents:
diff changeset
77 self.sizer.appendColum(0,chat)
goffi@necton2
parents:
diff changeset
78 self.sizer.update()
goffi@necton2
parents:
diff changeset
79 return chat
goffi@necton2
parents:
diff changeset
80
goffi@necton2
parents:
diff changeset
81
goffi@necton2
parents:
diff changeset
82 class ContactList(Window, QuickContactList):
goffi@necton2
parents:
diff changeset
83
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
84 def __init__(self, host, CM):
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
85 QuickContactList.__init__(self, CM)
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
86 self.host = host
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
87 self.jid_list = []
0
goffi@necton2
parents:
diff changeset
88 self.__index=0 #indicate which contact is selected (ie: where we are)
goffi@necton2
parents:
diff changeset
89 Window.__init__(self, stdscr, stdscr.getmaxyx()[0]-2,const_CONTACT_WIDTH,0,0, True, "Contact List", code=code)
goffi@necton2
parents:
diff changeset
90
goffi@necton2
parents:
diff changeset
91 def resize(self, height, width, y, x):
goffi@necton2
parents:
diff changeset
92 Window.resize(self, height, width, y, x)
goffi@necton2
parents:
diff changeset
93 self.update()
goffi@necton2
parents:
diff changeset
94
goffi@necton2
parents:
diff changeset
95 def resizeAdapt(self):
goffi@necton2
parents:
diff changeset
96 """Adapt window size to stdscr size.
goffi@necton2
parents:
diff changeset
97 Must be called when stdscr is resized."""
goffi@necton2
parents:
diff changeset
98 self.resize(stdscr.getmaxyx()[0]-2,const_CONTACT_WIDTH,0,0)
goffi@necton2
parents:
diff changeset
99 self.update()
goffi@necton2
parents:
diff changeset
100
goffi@necton2
parents:
diff changeset
101 def registerEnterCB(self, CB):
goffi@necton2
parents:
diff changeset
102 self.__enterCB=CB
goffi@necton2
parents:
diff changeset
103
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
104 def replace(self, jid):
0
goffi@necton2
parents:
diff changeset
105 """add a contact to the list"""
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
106 name = self.CM.getAttr(jid,'name')
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
107 self.jid_list.append(jid.short)
0
goffi@necton2
parents:
diff changeset
108 self.update()
goffi@necton2
parents:
diff changeset
109
goffi@necton2
parents:
diff changeset
110 def indexUp(self):
goffi@necton2
parents:
diff changeset
111 """increment select contact index"""
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
112 if self.__index < len(self.jid_list)-1: #we dont want to select a missing contact
0
goffi@necton2
parents:
diff changeset
113 self.__index = self.__index + 1
goffi@necton2
parents:
diff changeset
114 self.update()
goffi@necton2
parents:
diff changeset
115
goffi@necton2
parents:
diff changeset
116 def indexDown(self):
goffi@necton2
parents:
diff changeset
117 """decrement select contact index"""
goffi@necton2
parents:
diff changeset
118 if self.__index > 0:
goffi@necton2
parents:
diff changeset
119 self.__index = self.__index - 1
goffi@necton2
parents:
diff changeset
120 self.update()
goffi@necton2
parents:
diff changeset
121
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
122 def disconnect(self, jid):
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
123 """for now, we just remove the contact"""
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
124 self.remove(jid)
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
125
0
goffi@necton2
parents:
diff changeset
126 def remove(self, jid):
goffi@necton2
parents:
diff changeset
127 """remove a contact from the list"""
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
128 self.jid_list.remove(jid.short)
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
129 if self.__index >= len(self.jid_list) and self.__index > 0: #if select index is out of border, we put it on the last contact
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
130 self.__index = len(self.jid_list)-1
0
goffi@necton2
parents:
diff changeset
131 self.update()
goffi@necton2
parents:
diff changeset
132
goffi@necton2
parents:
diff changeset
133 def update(self):
goffi@necton2
parents:
diff changeset
134 """redraw all the window"""
goffi@necton2
parents:
diff changeset
135 if self.isHidden():
goffi@necton2
parents:
diff changeset
136 return
goffi@necton2
parents:
diff changeset
137 Window.update(self)
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
138 self.jid_list.sort()
0
goffi@necton2
parents:
diff changeset
139 begin=0 if self.__index<self.rHeight else self.__index-self.rHeight+1
goffi@necton2
parents:
diff changeset
140 idx=0
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
141 for item in self.jid_list[begin:self.rHeight+begin]:
0
goffi@necton2
parents:
diff changeset
142 attr = curses.A_REVERSE if ( self.isActive() and (idx+begin) == self.__index ) else 0
goffi@necton2
parents:
diff changeset
143 centered = item.center(self.rWidth) ## it's nicer in the center :)
goffi@necton2
parents:
diff changeset
144 self.addYXStr(idx, 0, centered, attr)
goffi@necton2
parents:
diff changeset
145 idx = idx + 1
goffi@necton2
parents:
diff changeset
146
goffi@necton2
parents:
diff changeset
147 self.noutrefresh()
goffi@necton2
parents:
diff changeset
148
goffi@necton2
parents:
diff changeset
149 def handleKey(self, k):
goffi@necton2
parents:
diff changeset
150 if k == curses.KEY_UP:
goffi@necton2
parents:
diff changeset
151 self.indexDown()
goffi@necton2
parents:
diff changeset
152 elif k == curses.KEY_DOWN:
goffi@necton2
parents:
diff changeset
153 self.indexUp()
goffi@necton2
parents:
diff changeset
154 elif k == ascii.NL:
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
155 if not self.jid_list:
0
goffi@necton2
parents:
diff changeset
156 return
goffi@necton2
parents:
diff changeset
157 try:
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
158 self.__enterCB(self.jid_list[self.__index])
0
goffi@necton2
parents:
diff changeset
159 except NameError:
goffi@necton2
parents:
diff changeset
160 pass # TODO: thrown an error here
goffi@necton2
parents:
diff changeset
161
goffi@necton2
parents:
diff changeset
162 class SortilegeApp(QuickApp):
goffi@necton2
parents:
diff changeset
163
goffi@necton2
parents:
diff changeset
164 def __init__(self):
goffi@necton2
parents:
diff changeset
165 #debug(const_APP_NAME+" init...")
goffi@necton2
parents:
diff changeset
166
goffi@necton2
parents:
diff changeset
167 ## unicode support ##
goffi@necton2
parents:
diff changeset
168 locale.setlocale(locale.LC_ALL, '')
goffi@necton2
parents:
diff changeset
169 global code
goffi@necton2
parents:
diff changeset
170 code = locale.getpreferredencoding()
goffi@necton2
parents:
diff changeset
171 self.code=code
goffi@necton2
parents:
diff changeset
172
goffi@necton2
parents:
diff changeset
173 ## main loop setup ##
goffi@necton2
parents:
diff changeset
174 self.loop=gobject.MainLoop()
goffi@necton2
parents:
diff changeset
175 gobject.io_add_watch(0, gobject.IO_IN, self.loopCB)
goffi@necton2
parents:
diff changeset
176
goffi@necton2
parents:
diff changeset
177 ## misc init stuff ##
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
178 self.CM = QuickContactManagement()
0
goffi@necton2
parents:
diff changeset
179 self.listWins=[]
goffi@necton2
parents:
diff changeset
180 self.chatParams={'timestamp':True,
goffi@necton2
parents:
diff changeset
181 'color':True,
goffi@necton2
parents:
diff changeset
182 'short_nick':False}
goffi@necton2
parents:
diff changeset
183
goffi@necton2
parents:
diff changeset
184 def start(self):
goffi@necton2
parents:
diff changeset
185 curses.wrapper(self.start_curses)
goffi@necton2
parents:
diff changeset
186
goffi@necton2
parents:
diff changeset
187 def start_curses(self, win):
goffi@necton2
parents:
diff changeset
188 global stdscr
goffi@necton2
parents:
diff changeset
189 stdscr = win
goffi@necton2
parents:
diff changeset
190 self.stdscr = stdscr
goffi@necton2
parents:
diff changeset
191 curses.raw() #we handle everything ourself
goffi@necton2
parents:
diff changeset
192 curses.curs_set(False)
goffi@necton2
parents:
diff changeset
193 stdscr.nodelay(True)
goffi@necton2
parents:
diff changeset
194
goffi@necton2
parents:
diff changeset
195 ## colours ##
goffi@necton2
parents:
diff changeset
196 self.color(True)
goffi@necton2
parents:
diff changeset
197
goffi@necton2
parents:
diff changeset
198 ## windows ##
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
199 self.contactList = ContactList(self, self.CM)
0
goffi@necton2
parents:
diff changeset
200 self.editBar = EditBox(stdscr, "> ", self.code)
goffi@necton2
parents:
diff changeset
201 self.editBar.activate(False)
goffi@necton2
parents:
diff changeset
202 self.statusBar = StatusBar(stdscr, self.code)
goffi@necton2
parents:
diff changeset
203 self.statusBar.hide(True)
goffi@necton2
parents:
diff changeset
204 self.addWin(self.contactList)
goffi@necton2
parents:
diff changeset
205 self.addWin(self.editBar)
goffi@necton2
parents:
diff changeset
206 self.addWin(self.statusBar)
goffi@necton2
parents:
diff changeset
207 self.sizer=BoxSizer(stdscr)
goffi@necton2
parents:
diff changeset
208 self.sizer.appendRow(self.contactList)
goffi@necton2
parents:
diff changeset
209 self.sizer.appendRow(self.statusBar)
goffi@necton2
parents:
diff changeset
210 self.sizer.appendRow(self.editBar)
goffi@necton2
parents:
diff changeset
211 self.currentChat=None
goffi@necton2
parents:
diff changeset
212
goffi@necton2
parents:
diff changeset
213 self.contactList.registerEnterCB(self.onContactChoosed)
goffi@necton2
parents:
diff changeset
214 self.editBar.registerEnterCB(self.onTextEntered)
goffi@necton2
parents:
diff changeset
215
goffi@necton2
parents:
diff changeset
216 self.chat_wins=ChatList(self)
goffi@necton2
parents:
diff changeset
217
goffi@necton2
parents:
diff changeset
218 QuickApp.__init__(self) #XXX: yes it's an unusual place for the constructor of a parent class, but the init order is important
goffi@necton2
parents:
diff changeset
219
goffi@necton2
parents:
diff changeset
220 signal (SIGWINCH, self.onResize) #we manage SIGWINCH ourselves, because the loop is not called otherwise
goffi@necton2
parents:
diff changeset
221
goffi@necton2
parents:
diff changeset
222 #last but not least, we adapt windows' sizes
goffi@necton2
parents:
diff changeset
223 self.sizer.update()
goffi@necton2
parents:
diff changeset
224 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
225 curses.doupdate()
goffi@necton2
parents:
diff changeset
226
goffi@necton2
parents:
diff changeset
227 self.loop.run()
goffi@necton2
parents:
diff changeset
228
goffi@necton2
parents:
diff changeset
229 def addWin(self, win):
goffi@necton2
parents:
diff changeset
230 self.listWins.append(win)
goffi@necton2
parents:
diff changeset
231
goffi@necton2
parents:
diff changeset
232 def color(self, activate=True):
goffi@necton2
parents:
diff changeset
233 if activate:
goffi@necton2
parents:
diff changeset
234 debug ("Activation des couleurs")
goffi@necton2
parents:
diff changeset
235 curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
236 curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
237 else:
goffi@necton2
parents:
diff changeset
238 debug ("Desactivation des couleurs")
goffi@necton2
parents:
diff changeset
239 curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
240 curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
241
goffi@necton2
parents:
diff changeset
242
goffi@necton2
parents:
diff changeset
243 def showChat(self, chat):
goffi@necton2
parents:
diff changeset
244 debug ("show chat")
goffi@necton2
parents:
diff changeset
245 if self.currentChat:
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
246 debug ("hiding %s", self.currentChat)
0
goffi@necton2
parents:
diff changeset
247 self.chat_wins[self.currentChat].hide()
goffi@necton2
parents:
diff changeset
248 self.currentChat=chat
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
249 debug ("showing %s", self.currentChat)
0
goffi@necton2
parents:
diff changeset
250 self.chat_wins[self.currentChat].show()
goffi@necton2
parents:
diff changeset
251 self.chat_wins[self.currentChat].update()
goffi@necton2
parents:
diff changeset
252
goffi@necton2
parents:
diff changeset
253
goffi@necton2
parents:
diff changeset
254 ### EVENTS ###
goffi@necton2
parents:
diff changeset
255
goffi@necton2
parents:
diff changeset
256 def onContactChoosed(self, jid_txt):
goffi@necton2
parents:
diff changeset
257 """Called when a contact is selected in contact list."""
goffi@necton2
parents:
diff changeset
258 jid=JID(jid_txt)
goffi@necton2
parents:
diff changeset
259 debug ("contact choose: %s", jid)
goffi@necton2
parents:
diff changeset
260 self.showChat(jid.short)
goffi@necton2
parents:
diff changeset
261 self.statusBar.remove_item(jid.short)
goffi@necton2
parents:
diff changeset
262 if len(self.statusBar)==0:
goffi@necton2
parents:
diff changeset
263 self.statusBar.hide()
goffi@necton2
parents:
diff changeset
264 self.sizer.update()
goffi@necton2
parents:
diff changeset
265
goffi@necton2
parents:
diff changeset
266
goffi@necton2
parents:
diff changeset
267 def onTextEntered(self, text):
goffi@necton2
parents:
diff changeset
268 jid=JID(self.whoami)
goffi@necton2
parents:
diff changeset
269 self.bridge.sendMessage(self.currentChat, text)
goffi@necton2
parents:
diff changeset
270
goffi@necton2
parents:
diff changeset
271 def showDialog(self, message, title, type="info"):
goffi@necton2
parents:
diff changeset
272 if type==question:
goffi@necton2
parents:
diff changeset
273 raise NotImplementedError
goffi@necton2
parents:
diff changeset
274 pass
goffi@necton2
parents:
diff changeset
275
goffi@necton2
parents:
diff changeset
276
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
277 def presenceUpdate(self, jabber_id, show, priority, statuses):
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
278 QuickApp.presenceUpdate(self, jabber_id, show, priority, statuses)
0
goffi@necton2
parents:
diff changeset
279 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
280 curses.doupdate()
goffi@necton2
parents:
diff changeset
281
22
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
282 def askConfirmation(self, type, id, data):
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
283 #FIXME
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
284 info ("FIXME: askConfirmation not implemented")
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
285
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
286 def actionResult(self, type, id, data):
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
287 #FIXME
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
288 info ("FIXME: actionResult not implemented")
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
289
0
goffi@necton2
parents:
diff changeset
290 def newMessage(self, from_jid, msg, type, to_jid):
goffi@necton2
parents:
diff changeset
291 QuickApp.newMessage(self, from_jid, msg, type, to_jid)
goffi@necton2
parents:
diff changeset
292 sender=JID(from_jid)
goffi@necton2
parents:
diff changeset
293 addr=JID(to_jid)
goffi@necton2
parents:
diff changeset
294 win = addr if sender.short == self.whoami.short else sender #FIXME: duplicate code with QuickApp
goffi@necton2
parents:
diff changeset
295 if (self.currentChat==None):
goffi@necton2
parents:
diff changeset
296 self.currentChat=win.short
goffi@necton2
parents:
diff changeset
297 self.showChat(win.short)
goffi@necton2
parents:
diff changeset
298
goffi@necton2
parents:
diff changeset
299 # we show the window in the status bar
goffi@necton2
parents:
diff changeset
300 if not self.currentChat == win.short:
goffi@necton2
parents:
diff changeset
301 self.statusBar.add_item(win.short)
goffi@necton2
parents:
diff changeset
302 self.statusBar.show()
goffi@necton2
parents:
diff changeset
303 self.sizer.update()
goffi@necton2
parents:
diff changeset
304 self.statusBar.update()
goffi@necton2
parents:
diff changeset
305
goffi@necton2
parents:
diff changeset
306 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
307 curses.doupdate()
goffi@necton2
parents:
diff changeset
308
goffi@necton2
parents:
diff changeset
309 def onResize(self, sig, stack):
goffi@necton2
parents:
diff changeset
310 """Called on SIGWINCH.
goffi@necton2
parents:
diff changeset
311 resize the screen and launch the loop"""
goffi@necton2
parents:
diff changeset
312 height, width = ttysize()
goffi@necton2
parents:
diff changeset
313 curses.resizeterm(height, width)
goffi@necton2
parents:
diff changeset
314 gobject.idle_add(self.callOnceLoop)
goffi@necton2
parents:
diff changeset
315
goffi@necton2
parents:
diff changeset
316 def callOnceLoop(self):
goffi@necton2
parents:
diff changeset
317 """Call the loop and return false (for not being called again by gobject mainloop).
goffi@necton2
parents:
diff changeset
318 Usefull for calling loop when there is no input in stdin"""
goffi@necton2
parents:
diff changeset
319 self.loopCB()
goffi@necton2
parents:
diff changeset
320 return False
goffi@necton2
parents:
diff changeset
321
goffi@necton2
parents:
diff changeset
322 def __key_handling(self, k):
goffi@necton2
parents:
diff changeset
323 """Handle key and transmit to active window."""
goffi@necton2
parents:
diff changeset
324
goffi@necton2
parents:
diff changeset
325 ### General keys, handled _everytime_ ###
goffi@necton2
parents:
diff changeset
326 if k == C('x'):
goffi@necton2
parents:
diff changeset
327 if os.getenv('TERM')=='screen':
goffi@necton2
parents:
diff changeset
328 os.system('screen -X remove')
goffi@necton2
parents:
diff changeset
329 else:
goffi@necton2
parents:
diff changeset
330 self.loop.quit()
goffi@necton2
parents:
diff changeset
331
goffi@necton2
parents:
diff changeset
332 ## windows navigation
goffi@necton2
parents:
diff changeset
333 elif k == C('l') and not self.contactList.isHidden():
goffi@necton2
parents:
diff changeset
334 """We go to the contact list"""
goffi@necton2
parents:
diff changeset
335 self.contactList.activate(not self.contactList.isActive())
goffi@necton2
parents:
diff changeset
336 if self.currentChat:
goffi@necton2
parents:
diff changeset
337 self.editBar.activate(not self.contactList.isActive())
goffi@necton2
parents:
diff changeset
338
goffi@necton2
parents:
diff changeset
339 elif k == curses.KEY_F2:
goffi@necton2
parents:
diff changeset
340 self.contactList.hide(not self.contactList.isHidden())
goffi@necton2
parents:
diff changeset
341 if self.contactList.isHidden():
goffi@necton2
parents:
diff changeset
342 self.contactList.activate(False) #TODO: auto deactivation when hiding ?
goffi@necton2
parents:
diff changeset
343 if self.currentChat:
goffi@necton2
parents:
diff changeset
344 self.editBar.activate(True)
goffi@necton2
parents:
diff changeset
345 self.sizer.update()
goffi@necton2
parents:
diff changeset
346
goffi@necton2
parents:
diff changeset
347 ## Chat Params ##
goffi@necton2
parents:
diff changeset
348 elif k == C('c'):
goffi@necton2
parents:
diff changeset
349 self.chatParams["color"] = not self.chatParams["color"]
goffi@necton2
parents:
diff changeset
350 self.color(self.chatParams["color"])
goffi@necton2
parents:
diff changeset
351 elif k == C('t'):
goffi@necton2
parents:
diff changeset
352 self.chatParams["timestamp"] = not self.chatParams["timestamp"]
goffi@necton2
parents:
diff changeset
353 self.chat_wins[self.currentChat].update()
goffi@necton2
parents:
diff changeset
354 elif k == C('s'):
goffi@necton2
parents:
diff changeset
355 self.chatParams["short_nick"] = not self.chatParams["short_nick"]
goffi@necton2
parents:
diff changeset
356 self.chat_wins[self.currentChat].update()
goffi@necton2
parents:
diff changeset
357
goffi@necton2
parents:
diff changeset
358 ## misc ##
goffi@necton2
parents:
diff changeset
359 elif k == curses.KEY_RESIZE:
goffi@necton2
parents:
diff changeset
360 stdscr.erase()
goffi@necton2
parents:
diff changeset
361 height, width = stdscr.getmaxyx()
goffi@necton2
parents:
diff changeset
362 if height<5 and width<35:
goffi@necton2
parents:
diff changeset
363 stdscr.addstr("Pleeeeasse, I can't even breathe !")
goffi@necton2
parents:
diff changeset
364 else:
goffi@necton2
parents:
diff changeset
365 for win in self.listWins:
goffi@necton2
parents:
diff changeset
366 win.resizeAdapt()
goffi@necton2
parents:
diff changeset
367 for win in self.chat_wins.keys():
goffi@necton2
parents:
diff changeset
368 self.chat_wins[win].resizeAdapt()
goffi@necton2
parents:
diff changeset
369 self.sizer.update() # FIXME: everything need to be managed by the sizer
goffi@necton2
parents:
diff changeset
370
goffi@necton2
parents:
diff changeset
371 ## we now throw the key to win handlers ##
goffi@necton2
parents:
diff changeset
372 else:
goffi@necton2
parents:
diff changeset
373 for win in self.listWins:
goffi@necton2
parents:
diff changeset
374 if win.isActive():
goffi@necton2
parents:
diff changeset
375 win.handleKey(k)
goffi@necton2
parents:
diff changeset
376 if self.currentChat:
goffi@necton2
parents:
diff changeset
377 self.chat_wins[self.currentChat].handleKey(k)
goffi@necton2
parents:
diff changeset
378
goffi@necton2
parents:
diff changeset
379 def loopCB(self, source="", cb_condition=""):
goffi@necton2
parents:
diff changeset
380 """This callback is called by the main loop"""
goffi@necton2
parents:
diff changeset
381 #pressed = self.contactList.window.getch()
goffi@necton2
parents:
diff changeset
382 pressed = stdscr.getch()
goffi@necton2
parents:
diff changeset
383 if pressed != curses.ERR:
goffi@necton2
parents:
diff changeset
384 self.__key_handling(pressed)
goffi@necton2
parents:
diff changeset
385 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
386 curses.doupdate()
goffi@necton2
parents:
diff changeset
387
goffi@necton2
parents:
diff changeset
388
goffi@necton2
parents:
diff changeset
389 return True
goffi@necton2
parents:
diff changeset
390
goffi@necton2
parents:
diff changeset
391
goffi@necton2
parents:
diff changeset
392 sat = SortilegeApp()
goffi@necton2
parents:
diff changeset
393 sat.start()