annotate frontends/sortilege_old/sortilege @ 510:886754295efe

quick frontend, primitivus, wix: MUC private messages management /!\ not fully finished, backend part is not done yet /!\ - as resources are discarded to manage chat windows lists, a pretty dirty hack is done to work around this: full jid is escaped using a prefix (it becomes invalid and resource is preserved). - new quick_utils module, with helper methods. escapePrivate and unescapePrivate implementations - MUC private messages are not managed in Wix yet
author Goffi <goffi@goffi.org>
date Thu, 11 Oct 2012 00:48:35 +0200
parents 2a072735e459
children 952322b1d490
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
57
a5b5fb5fc9fd updated README and copyright note
Goffi <goffi@goffi.org>
parents: 52
diff changeset
6 Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org)
0
goffi@necton2
parents:
diff changeset
7
goffi@necton2
parents:
diff changeset
8 This program is free software: you can redistribute it and/or modify
480
2a072735e459 Licence modification: the full project is now under AGPL v3+ instead of GPL v3+
Goffi <goffi@goffi.org>
parents: 112
diff changeset
9 it under the terms of the GNU Affero General Public License as published by
0
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
480
2a072735e459 Licence modification: the full project is now under AGPL v3+ instead of GPL v3+
Goffi <goffi@goffi.org>
parents: 112
diff changeset
16 GNU Affero General Public License for more details.
0
goffi@necton2
parents:
diff changeset
17
480
2a072735e459 Licence modification: the full project is now under AGPL v3+ instead of GPL v3+
Goffi <goffi@goffi.org>
parents: 112
diff changeset
18 You should have received a copy of the GNU Affero General Public License
0
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
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
23 from quick_frontend.quick_app import QuickApp
Goffi <goffi@goffi.org>
parents: 67
diff changeset
24 from quick_frontend.quick_chat_list import QuickChatList
Goffi <goffi@goffi.org>
parents: 67
diff changeset
25 from quick_frontend.quick_contact_list import QuickContactList
Goffi <goffi@goffi.org>
parents: 67
diff changeset
26 from quick_frontend.quick_contact_management import QuickContactManagement
0
goffi@necton2
parents:
diff changeset
27 import curses
goffi@necton2
parents:
diff changeset
28 import pdb
goffi@necton2
parents:
diff changeset
29 from window import Window
goffi@necton2
parents:
diff changeset
30 from editbox import EditBox
goffi@necton2
parents:
diff changeset
31 from statusbar import StatusBar
goffi@necton2
parents:
diff changeset
32 from chat import Chat
goffi@necton2
parents:
diff changeset
33 from tools.jid import JID
goffi@necton2
parents:
diff changeset
34 import logging
goffi@necton2
parents:
diff changeset
35 from logging import debug, info, error
goffi@necton2
parents:
diff changeset
36 import locale
goffi@necton2
parents:
diff changeset
37 import sys, os
goffi@necton2
parents:
diff changeset
38 import gobject
goffi@necton2
parents:
diff changeset
39 import time
goffi@necton2
parents:
diff changeset
40 from curses import ascii
goffi@necton2
parents:
diff changeset
41 import locale
goffi@necton2
parents:
diff changeset
42 from signal import signal, SIGWINCH
goffi@necton2
parents:
diff changeset
43 import fcntl
goffi@necton2
parents:
diff changeset
44 import struct
goffi@necton2
parents:
diff changeset
45 import termios
goffi@necton2
parents:
diff changeset
46 from boxsizer import BoxSizer
goffi@necton2
parents:
diff changeset
47
52
6455fb62ff83 Connection/disconnection signals
Goffi <goffi@goffi.org>
parents: 51
diff changeset
48
0
goffi@necton2
parents:
diff changeset
49 ### logging configuration FIXME: put this elsewhere ###
goffi@necton2
parents:
diff changeset
50 logging.basicConfig(level=logging.CRITICAL, #TODO: configure it top put messages in a log file
goffi@necton2
parents:
diff changeset
51 format='%(message)s')
goffi@necton2
parents:
diff changeset
52 ###
goffi@necton2
parents:
diff changeset
53
goffi@necton2
parents:
diff changeset
54 const_APP_NAME = "Sortilège"
goffi@necton2
parents:
diff changeset
55 const_CONTACT_WIDTH = 30
goffi@necton2
parents:
diff changeset
56
goffi@necton2
parents:
diff changeset
57 def ttysize():
goffi@necton2
parents:
diff changeset
58 """This function return term size.
goffi@necton2
parents:
diff changeset
59 Comes from Donn Cave from python list mailing list"""
goffi@necton2
parents:
diff changeset
60 buf = 'abcdefgh'
goffi@necton2
parents:
diff changeset
61 buf = fcntl.ioctl(0, termios.TIOCGWINSZ, buf)
goffi@necton2
parents:
diff changeset
62 row, col, rpx, cpx = struct.unpack('hhhh', buf)
goffi@necton2
parents:
diff changeset
63 return row, col
goffi@necton2
parents:
diff changeset
64
goffi@necton2
parents:
diff changeset
65 def C(k):
goffi@necton2
parents:
diff changeset
66 """return the value of Ctrl+key"""
goffi@necton2
parents:
diff changeset
67 return ord(ascii.ctrl(k))
goffi@necton2
parents:
diff changeset
68
goffi@necton2
parents:
diff changeset
69 class ChatList(QuickChatList):
goffi@necton2
parents:
diff changeset
70 """This class manage the list of chat windows"""
goffi@necton2
parents:
diff changeset
71
goffi@necton2
parents:
diff changeset
72 def __init__(self, host):
goffi@necton2
parents:
diff changeset
73 QuickChatList.__init__(self, host)
goffi@necton2
parents:
diff changeset
74 self.sizer=host.sizer
goffi@necton2
parents:
diff changeset
75
goffi@necton2
parents:
diff changeset
76 def createChat(self, name):
goffi@necton2
parents:
diff changeset
77 chat = Chat(name, self.host)
goffi@necton2
parents:
diff changeset
78 self.sizer.appendColum(0,chat)
goffi@necton2
parents:
diff changeset
79 self.sizer.update()
goffi@necton2
parents:
diff changeset
80 return chat
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)
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
89 Window.__init__(self, stdscr, stdscr.getmaxyx()[0]-2,const_CONTACT_WIDTH,0,0, True, _("Contact List"), code=code)
0
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
52
6455fb62ff83 Connection/disconnection signals
Goffi <goffi@goffi.org>
parents: 51
diff changeset
104 def clear_contacts(self):
6455fb62ff83 Connection/disconnection signals
Goffi <goffi@goffi.org>
parents: 51
diff changeset
105 """clear all the contact list"""
6455fb62ff83 Connection/disconnection signals
Goffi <goffi@goffi.org>
parents: 51
diff changeset
106 del self.jid_list[:]
6455fb62ff83 Connection/disconnection signals
Goffi <goffi@goffi.org>
parents: 51
diff changeset
107 self.__index = 0
6455fb62ff83 Connection/disconnection signals
Goffi <goffi@goffi.org>
parents: 51
diff changeset
108 self.update() #FIXME: window is not updated correctly (contacts are still here until C-L)
6455fb62ff83 Connection/disconnection signals
Goffi <goffi@goffi.org>
parents: 51
diff changeset
109
111
6c927140ba82 sortilege fix: it launches again now
Goffi <goffi@goffi.org>
parents: 70
diff changeset
110 def replace(self, jid, groups=None):
0
goffi@necton2
parents:
diff changeset
111 """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
112 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
113 self.jid_list.append(jid.short)
0
goffi@necton2
parents:
diff changeset
114 self.update()
goffi@necton2
parents:
diff changeset
115
goffi@necton2
parents:
diff changeset
116 def indexUp(self):
goffi@necton2
parents:
diff changeset
117 """increment select contact index"""
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
118 if self.__index < len(self.jid_list)-1: #we dont want to select a missing contact
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
goffi@necton2
parents:
diff changeset
122 def indexDown(self):
goffi@necton2
parents:
diff changeset
123 """decrement select contact index"""
goffi@necton2
parents:
diff changeset
124 if self.__index > 0:
goffi@necton2
parents:
diff changeset
125 self.__index = self.__index - 1
goffi@necton2
parents:
diff changeset
126 self.update()
goffi@necton2
parents:
diff changeset
127
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
128 def disconnect(self, jid):
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
129 """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
130 self.remove(jid)
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
131
0
goffi@necton2
parents:
diff changeset
132 def remove(self, jid):
goffi@necton2
parents:
diff changeset
133 """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
134 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
135 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
136 self.__index = len(self.jid_list)-1
0
goffi@necton2
parents:
diff changeset
137 self.update()
goffi@necton2
parents:
diff changeset
138
goffi@necton2
parents:
diff changeset
139 def update(self):
goffi@necton2
parents:
diff changeset
140 """redraw all the window"""
goffi@necton2
parents:
diff changeset
141 if self.isHidden():
goffi@necton2
parents:
diff changeset
142 return
goffi@necton2
parents:
diff changeset
143 Window.update(self)
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
144 self.jid_list.sort()
0
goffi@necton2
parents:
diff changeset
145 begin=0 if self.__index<self.rHeight else self.__index-self.rHeight+1
goffi@necton2
parents:
diff changeset
146 idx=0
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
147 for item in self.jid_list[begin:self.rHeight+begin]:
0
goffi@necton2
parents:
diff changeset
148 attr = curses.A_REVERSE if ( self.isActive() and (idx+begin) == self.__index ) else 0
goffi@necton2
parents:
diff changeset
149 centered = item.center(self.rWidth) ## it's nicer in the center :)
goffi@necton2
parents:
diff changeset
150 self.addYXStr(idx, 0, centered, attr)
goffi@necton2
parents:
diff changeset
151 idx = idx + 1
goffi@necton2
parents:
diff changeset
152
goffi@necton2
parents:
diff changeset
153 self.noutrefresh()
goffi@necton2
parents:
diff changeset
154
goffi@necton2
parents:
diff changeset
155 def handleKey(self, k):
goffi@necton2
parents:
diff changeset
156 if k == curses.KEY_UP:
goffi@necton2
parents:
diff changeset
157 self.indexDown()
goffi@necton2
parents:
diff changeset
158 elif k == curses.KEY_DOWN:
goffi@necton2
parents:
diff changeset
159 self.indexUp()
goffi@necton2
parents:
diff changeset
160 elif k == ascii.NL:
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
161 if not self.jid_list:
0
goffi@necton2
parents:
diff changeset
162 return
goffi@necton2
parents:
diff changeset
163 try:
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
164 self.__enterCB(self.jid_list[self.__index])
0
goffi@necton2
parents:
diff changeset
165 except NameError:
goffi@necton2
parents:
diff changeset
166 pass # TODO: thrown an error here
goffi@necton2
parents:
diff changeset
167
goffi@necton2
parents:
diff changeset
168 class SortilegeApp(QuickApp):
goffi@necton2
parents:
diff changeset
169
goffi@necton2
parents:
diff changeset
170 def __init__(self):
goffi@necton2
parents:
diff changeset
171 #debug(const_APP_NAME+" init...")
goffi@necton2
parents:
diff changeset
172
goffi@necton2
parents:
diff changeset
173 ## unicode support ##
goffi@necton2
parents:
diff changeset
174 locale.setlocale(locale.LC_ALL, '')
goffi@necton2
parents:
diff changeset
175 global code
goffi@necton2
parents:
diff changeset
176 code = locale.getpreferredencoding()
goffi@necton2
parents:
diff changeset
177 self.code=code
goffi@necton2
parents:
diff changeset
178
goffi@necton2
parents:
diff changeset
179 ## main loop setup ##
goffi@necton2
parents:
diff changeset
180 self.loop=gobject.MainLoop()
goffi@necton2
parents:
diff changeset
181 gobject.io_add_watch(0, gobject.IO_IN, self.loopCB)
goffi@necton2
parents:
diff changeset
182
goffi@necton2
parents:
diff changeset
183 ## misc init stuff ##
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
184 self.CM = QuickContactManagement()
0
goffi@necton2
parents:
diff changeset
185 self.listWins=[]
goffi@necton2
parents:
diff changeset
186 self.chatParams={'timestamp':True,
goffi@necton2
parents:
diff changeset
187 'color':True,
goffi@necton2
parents:
diff changeset
188 'short_nick':False}
goffi@necton2
parents:
diff changeset
189
goffi@necton2
parents:
diff changeset
190 def start(self):
goffi@necton2
parents:
diff changeset
191 curses.wrapper(self.start_curses)
goffi@necton2
parents:
diff changeset
192
goffi@necton2
parents:
diff changeset
193 def start_curses(self, win):
goffi@necton2
parents:
diff changeset
194 global stdscr
goffi@necton2
parents:
diff changeset
195 stdscr = win
goffi@necton2
parents:
diff changeset
196 self.stdscr = stdscr
goffi@necton2
parents:
diff changeset
197 curses.raw() #we handle everything ourself
goffi@necton2
parents:
diff changeset
198 curses.curs_set(False)
goffi@necton2
parents:
diff changeset
199 stdscr.nodelay(True)
goffi@necton2
parents:
diff changeset
200
goffi@necton2
parents:
diff changeset
201 ## colours ##
goffi@necton2
parents:
diff changeset
202 self.color(True)
goffi@necton2
parents:
diff changeset
203
goffi@necton2
parents:
diff changeset
204 ## windows ##
51
8c67ea98ab91 frontend improved to take into account new SàT features
Goffi <goffi@goffi.org>
parents: 32
diff changeset
205 self.contactList = ContactList(self, self.CM)
0
goffi@necton2
parents:
diff changeset
206 self.editBar = EditBox(stdscr, "> ", self.code)
goffi@necton2
parents:
diff changeset
207 self.editBar.activate(False)
goffi@necton2
parents:
diff changeset
208 self.statusBar = StatusBar(stdscr, self.code)
goffi@necton2
parents:
diff changeset
209 self.statusBar.hide(True)
goffi@necton2
parents:
diff changeset
210 self.addWin(self.contactList)
goffi@necton2
parents:
diff changeset
211 self.addWin(self.editBar)
goffi@necton2
parents:
diff changeset
212 self.addWin(self.statusBar)
goffi@necton2
parents:
diff changeset
213 self.sizer=BoxSizer(stdscr)
goffi@necton2
parents:
diff changeset
214 self.sizer.appendRow(self.contactList)
goffi@necton2
parents:
diff changeset
215 self.sizer.appendRow(self.statusBar)
goffi@necton2
parents:
diff changeset
216 self.sizer.appendRow(self.editBar)
goffi@necton2
parents:
diff changeset
217 self.currentChat=None
goffi@necton2
parents:
diff changeset
218
goffi@necton2
parents:
diff changeset
219 self.contactList.registerEnterCB(self.onContactChoosed)
goffi@necton2
parents:
diff changeset
220 self.editBar.registerEnterCB(self.onTextEntered)
goffi@necton2
parents:
diff changeset
221
goffi@necton2
parents:
diff changeset
222 self.chat_wins=ChatList(self)
goffi@necton2
parents:
diff changeset
223
goffi@necton2
parents:
diff changeset
224 QuickApp.__init__(self) #XXX: yes it's an unusual place for the constructor of a parent class, but the init order is important
67
0e50dd3a234a message sending bug fixes + sortilege update
Goffi <goffi@goffi.org>
parents: 57
diff changeset
225 self.plug_profile()
0
goffi@necton2
parents:
diff changeset
226
goffi@necton2
parents:
diff changeset
227 signal (SIGWINCH, self.onResize) #we manage SIGWINCH ourselves, because the loop is not called otherwise
goffi@necton2
parents:
diff changeset
228
goffi@necton2
parents:
diff changeset
229 #last but not least, we adapt windows' sizes
goffi@necton2
parents:
diff changeset
230 self.sizer.update()
goffi@necton2
parents:
diff changeset
231 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
232 curses.doupdate()
goffi@necton2
parents:
diff changeset
233
goffi@necton2
parents:
diff changeset
234 self.loop.run()
goffi@necton2
parents:
diff changeset
235
goffi@necton2
parents:
diff changeset
236 def addWin(self, win):
goffi@necton2
parents:
diff changeset
237 self.listWins.append(win)
goffi@necton2
parents:
diff changeset
238
goffi@necton2
parents:
diff changeset
239 def color(self, activate=True):
goffi@necton2
parents:
diff changeset
240 if activate:
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
241 debug (_("Activating colors"))
0
goffi@necton2
parents:
diff changeset
242 curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
243 curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
244 else:
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
245 debug (_("Deactivating colors"))
0
goffi@necton2
parents:
diff changeset
246 curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
247 curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
goffi@necton2
parents:
diff changeset
248
goffi@necton2
parents:
diff changeset
249
goffi@necton2
parents:
diff changeset
250 def showChat(self, chat):
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
251 debug (_("show chat"))
0
goffi@necton2
parents:
diff changeset
252 if self.currentChat:
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
253 debug (_("hiding %s"), self.currentChat)
0
goffi@necton2
parents:
diff changeset
254 self.chat_wins[self.currentChat].hide()
goffi@necton2
parents:
diff changeset
255 self.currentChat=chat
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
256 debug (_("showing %s"), self.currentChat)
0
goffi@necton2
parents:
diff changeset
257 self.chat_wins[self.currentChat].show()
goffi@necton2
parents:
diff changeset
258 self.chat_wins[self.currentChat].update()
goffi@necton2
parents:
diff changeset
259
goffi@necton2
parents:
diff changeset
260
goffi@necton2
parents:
diff changeset
261 ### EVENTS ###
goffi@necton2
parents:
diff changeset
262
goffi@necton2
parents:
diff changeset
263 def onContactChoosed(self, jid_txt):
goffi@necton2
parents:
diff changeset
264 """Called when a contact is selected in contact list."""
goffi@necton2
parents:
diff changeset
265 jid=JID(jid_txt)
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
266 debug (_("contact choosed: %s"), jid)
0
goffi@necton2
parents:
diff changeset
267 self.showChat(jid.short)
goffi@necton2
parents:
diff changeset
268 self.statusBar.remove_item(jid.short)
goffi@necton2
parents:
diff changeset
269 if len(self.statusBar)==0:
goffi@necton2
parents:
diff changeset
270 self.statusBar.hide()
goffi@necton2
parents:
diff changeset
271 self.sizer.update()
goffi@necton2
parents:
diff changeset
272
goffi@necton2
parents:
diff changeset
273
goffi@necton2
parents:
diff changeset
274 def onTextEntered(self, text):
67
0e50dd3a234a message sending bug fixes + sortilege update
Goffi <goffi@goffi.org>
parents: 57
diff changeset
275 jid=JID(self.profiles[self.profile]['whoami'])
0e50dd3a234a message sending bug fixes + sortilege update
Goffi <goffi@goffi.org>
parents: 57
diff changeset
276 self.bridge.sendMessage(self.currentChat, text, profile_key=self.profile)
0
goffi@necton2
parents:
diff changeset
277
goffi@necton2
parents:
diff changeset
278 def showDialog(self, message, title, type="info"):
goffi@necton2
parents:
diff changeset
279 if type==question:
goffi@necton2
parents:
diff changeset
280 raise NotImplementedError
goffi@necton2
parents:
diff changeset
281 pass
goffi@necton2
parents:
diff changeset
282
goffi@necton2
parents:
diff changeset
283
67
0e50dd3a234a message sending bug fixes + sortilege update
Goffi <goffi@goffi.org>
parents: 57
diff changeset
284 def presenceUpdate(self, jabber_id, show, priority, statuses, profile):
0e50dd3a234a message sending bug fixes + sortilege update
Goffi <goffi@goffi.org>
parents: 57
diff changeset
285 QuickApp.presenceUpdate(self, jabber_id, show, priority, statuses, profile)
0
goffi@necton2
parents:
diff changeset
286 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
287 curses.doupdate()
goffi@necton2
parents:
diff changeset
288
22
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
289 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
290 #FIXME
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
291 info (_("FIXME: askConfirmation not implemented"))
22
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
292
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
293 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
294 #FIXME
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
295 info (_("FIXME: actionResult not implemented"))
22
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 0
diff changeset
296
67
0e50dd3a234a message sending bug fixes + sortilege update
Goffi <goffi@goffi.org>
parents: 57
diff changeset
297 def newMessage(self, from_jid, msg, type, to_jid, profile):
0e50dd3a234a message sending bug fixes + sortilege update
Goffi <goffi@goffi.org>
parents: 57
diff changeset
298 QuickApp.newMessage(self, from_jid, msg, type, to_jid, profile)
0
goffi@necton2
parents:
diff changeset
299 sender=JID(from_jid)
goffi@necton2
parents:
diff changeset
300 addr=JID(to_jid)
goffi@necton2
parents:
diff changeset
301 win = addr if sender.short == self.whoami.short else sender #FIXME: duplicate code with QuickApp
goffi@necton2
parents:
diff changeset
302 if (self.currentChat==None):
goffi@necton2
parents:
diff changeset
303 self.currentChat=win.short
goffi@necton2
parents:
diff changeset
304 self.showChat(win.short)
goffi@necton2
parents:
diff changeset
305
goffi@necton2
parents:
diff changeset
306 # we show the window in the status bar
goffi@necton2
parents:
diff changeset
307 if not self.currentChat == win.short:
goffi@necton2
parents:
diff changeset
308 self.statusBar.add_item(win.short)
goffi@necton2
parents:
diff changeset
309 self.statusBar.show()
goffi@necton2
parents:
diff changeset
310 self.sizer.update()
goffi@necton2
parents:
diff changeset
311 self.statusBar.update()
goffi@necton2
parents:
diff changeset
312
goffi@necton2
parents:
diff changeset
313 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
314 curses.doupdate()
goffi@necton2
parents:
diff changeset
315
goffi@necton2
parents:
diff changeset
316 def onResize(self, sig, stack):
goffi@necton2
parents:
diff changeset
317 """Called on SIGWINCH.
goffi@necton2
parents:
diff changeset
318 resize the screen and launch the loop"""
goffi@necton2
parents:
diff changeset
319 height, width = ttysize()
goffi@necton2
parents:
diff changeset
320 curses.resizeterm(height, width)
goffi@necton2
parents:
diff changeset
321 gobject.idle_add(self.callOnceLoop)
goffi@necton2
parents:
diff changeset
322
goffi@necton2
parents:
diff changeset
323 def callOnceLoop(self):
goffi@necton2
parents:
diff changeset
324 """Call the loop and return false (for not being called again by gobject mainloop).
goffi@necton2
parents:
diff changeset
325 Usefull for calling loop when there is no input in stdin"""
goffi@necton2
parents:
diff changeset
326 self.loopCB()
goffi@necton2
parents:
diff changeset
327 return False
goffi@necton2
parents:
diff changeset
328
goffi@necton2
parents:
diff changeset
329 def __key_handling(self, k):
goffi@necton2
parents:
diff changeset
330 """Handle key and transmit to active window."""
goffi@necton2
parents:
diff changeset
331
goffi@necton2
parents:
diff changeset
332 ### General keys, handled _everytime_ ###
goffi@necton2
parents:
diff changeset
333 if k == C('x'):
goffi@necton2
parents:
diff changeset
334 if os.getenv('TERM')=='screen':
goffi@necton2
parents:
diff changeset
335 os.system('screen -X remove')
goffi@necton2
parents:
diff changeset
336 else:
goffi@necton2
parents:
diff changeset
337 self.loop.quit()
goffi@necton2
parents:
diff changeset
338
goffi@necton2
parents:
diff changeset
339 ## windows navigation
goffi@necton2
parents:
diff changeset
340 elif k == C('l') and not self.contactList.isHidden():
goffi@necton2
parents:
diff changeset
341 """We go to the contact list"""
goffi@necton2
parents:
diff changeset
342 self.contactList.activate(not self.contactList.isActive())
goffi@necton2
parents:
diff changeset
343 if self.currentChat:
goffi@necton2
parents:
diff changeset
344 self.editBar.activate(not self.contactList.isActive())
goffi@necton2
parents:
diff changeset
345
goffi@necton2
parents:
diff changeset
346 elif k == curses.KEY_F2:
goffi@necton2
parents:
diff changeset
347 self.contactList.hide(not self.contactList.isHidden())
goffi@necton2
parents:
diff changeset
348 if self.contactList.isHidden():
goffi@necton2
parents:
diff changeset
349 self.contactList.activate(False) #TODO: auto deactivation when hiding ?
goffi@necton2
parents:
diff changeset
350 if self.currentChat:
goffi@necton2
parents:
diff changeset
351 self.editBar.activate(True)
goffi@necton2
parents:
diff changeset
352 self.sizer.update()
goffi@necton2
parents:
diff changeset
353
goffi@necton2
parents:
diff changeset
354 ## Chat Params ##
goffi@necton2
parents:
diff changeset
355 elif k == C('c'):
goffi@necton2
parents:
diff changeset
356 self.chatParams["color"] = not self.chatParams["color"]
goffi@necton2
parents:
diff changeset
357 self.color(self.chatParams["color"])
goffi@necton2
parents:
diff changeset
358 elif k == C('t'):
goffi@necton2
parents:
diff changeset
359 self.chatParams["timestamp"] = not self.chatParams["timestamp"]
goffi@necton2
parents:
diff changeset
360 self.chat_wins[self.currentChat].update()
goffi@necton2
parents:
diff changeset
361 elif k == C('s'):
goffi@necton2
parents:
diff changeset
362 self.chatParams["short_nick"] = not self.chatParams["short_nick"]
goffi@necton2
parents:
diff changeset
363 self.chat_wins[self.currentChat].update()
goffi@necton2
parents:
diff changeset
364
goffi@necton2
parents:
diff changeset
365 ## misc ##
goffi@necton2
parents:
diff changeset
366 elif k == curses.KEY_RESIZE:
goffi@necton2
parents:
diff changeset
367 stdscr.erase()
goffi@necton2
parents:
diff changeset
368 height, width = stdscr.getmaxyx()
goffi@necton2
parents:
diff changeset
369 if height<5 and width<35:
70
Goffi <goffi@goffi.org>
parents: 67
diff changeset
370 stdscr.addstr(_("Pleeeeasse, I can't even breathe !"))
0
goffi@necton2
parents:
diff changeset
371 else:
goffi@necton2
parents:
diff changeset
372 for win in self.listWins:
goffi@necton2
parents:
diff changeset
373 win.resizeAdapt()
goffi@necton2
parents:
diff changeset
374 for win in self.chat_wins.keys():
goffi@necton2
parents:
diff changeset
375 self.chat_wins[win].resizeAdapt()
goffi@necton2
parents:
diff changeset
376 self.sizer.update() # FIXME: everything need to be managed by the sizer
goffi@necton2
parents:
diff changeset
377
goffi@necton2
parents:
diff changeset
378 ## we now throw the key to win handlers ##
goffi@necton2
parents:
diff changeset
379 else:
goffi@necton2
parents:
diff changeset
380 for win in self.listWins:
goffi@necton2
parents:
diff changeset
381 if win.isActive():
goffi@necton2
parents:
diff changeset
382 win.handleKey(k)
goffi@necton2
parents:
diff changeset
383 if self.currentChat:
goffi@necton2
parents:
diff changeset
384 self.chat_wins[self.currentChat].handleKey(k)
goffi@necton2
parents:
diff changeset
385
goffi@necton2
parents:
diff changeset
386 def loopCB(self, source="", cb_condition=""):
goffi@necton2
parents:
diff changeset
387 """This callback is called by the main loop"""
goffi@necton2
parents:
diff changeset
388 #pressed = self.contactList.window.getch()
goffi@necton2
parents:
diff changeset
389 pressed = stdscr.getch()
goffi@necton2
parents:
diff changeset
390 if pressed != curses.ERR:
goffi@necton2
parents:
diff changeset
391 self.__key_handling(pressed)
goffi@necton2
parents:
diff changeset
392 self.editBar.replace_cur()
goffi@necton2
parents:
diff changeset
393 curses.doupdate()
goffi@necton2
parents:
diff changeset
394
goffi@necton2
parents:
diff changeset
395
goffi@necton2
parents:
diff changeset
396 return True
goffi@necton2
parents:
diff changeset
397
goffi@necton2
parents:
diff changeset
398
goffi@necton2
parents:
diff changeset
399 sat = SortilegeApp()
goffi@necton2
parents:
diff changeset
400 sat.start()