comparison 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
comparison
equal deleted inserted replaced
50:daa1f01a5332 51:8c67ea98ab91
41 import termios 41 import termios
42 from boxsizer import BoxSizer 42 from boxsizer import BoxSizer
43 from quick_frontend.quick_chat_list import QuickChatList 43 from quick_frontend.quick_chat_list import QuickChatList
44 from quick_frontend.quick_contact_list import QuickContactList 44 from quick_frontend.quick_contact_list import QuickContactList
45 from quick_frontend.quick_app import QuickApp 45 from quick_frontend.quick_app import QuickApp
46 from quick_frontend.quick_contact_management import QuickContactManagement
46 47
47 ### logging configuration FIXME: put this elsewhere ### 48 ### logging configuration FIXME: put this elsewhere ###
48 logging.basicConfig(level=logging.CRITICAL, #TODO: configure it top put messages in a log file 49 logging.basicConfig(level=logging.CRITICAL, #TODO: configure it top put messages in a log file
49 format='%(message)s') 50 format='%(message)s')
50 ### 51 ###
78 return chat 79 return chat
79 80
80 81
81 class ContactList(Window, QuickContactList): 82 class ContactList(Window, QuickContactList):
82 83
83 def __init__(self): 84 def __init__(self, host, CM):
84 QuickContactList.__init__(self) 85 QuickContactList.__init__(self, CM)
86 self.host = host
87 self.jid_list = []
85 self.__index=0 #indicate which contact is selected (ie: where we are) 88 self.__index=0 #indicate which contact is selected (ie: where we are)
86 Window.__init__(self, stdscr, stdscr.getmaxyx()[0]-2,const_CONTACT_WIDTH,0,0, True, "Contact List", code=code) 89 Window.__init__(self, stdscr, stdscr.getmaxyx()[0]-2,const_CONTACT_WIDTH,0,0, True, "Contact List", code=code)
87 90
88 def resize(self, height, width, y, x): 91 def resize(self, height, width, y, x):
89 Window.resize(self, height, width, y, x) 92 Window.resize(self, height, width, y, x)
96 self.update() 99 self.update()
97 100
98 def registerEnterCB(self, CB): 101 def registerEnterCB(self, CB):
99 self.__enterCB=CB 102 self.__enterCB=CB
100 103
101 def replace(self, jid, name="", show="", status="", group=""): 104 def replace(self, jid):
102 """add a contact to the list""" 105 """add a contact to the list"""
103 self.jid_ids[jid] = name or jid 106 name = self.CM.getAttr(jid,'name')
107 self.jid_list.append(jid.short)
104 self.update() 108 self.update()
105 109
106 def indexUp(self): 110 def indexUp(self):
107 """increment select contact index""" 111 """increment select contact index"""
108 if self.__index < len(self.jid_ids)-1: #we dont want to select a missing contact 112 if self.__index < len(self.jid_list)-1: #we dont want to select a missing contact
109 self.__index = self.__index + 1 113 self.__index = self.__index + 1
110 self.update() 114 self.update()
111 115
112 def indexDown(self): 116 def indexDown(self):
113 """decrement select contact index""" 117 """decrement select contact index"""
114 if self.__index > 0: 118 if self.__index > 0:
115 self.__index = self.__index - 1 119 self.__index = self.__index - 1
116 self.update() 120 self.update()
117 121
122 def disconnect(self, jid):
123 """for now, we just remove the contact"""
124 self.remove(jid)
125
118 def remove(self, jid): 126 def remove(self, jid):
119 """remove a contact from the list""" 127 """remove a contact from the list"""
120 del self.jid_ids[jid] 128 self.jid_list.remove(jid.short)
121 if self.__index >= len(self.jid_ids) and self.__index > 0: #if select index is out of border, we put it on the last contact 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
122 self.__index = len(self.jid_ids)-1 130 self.__index = len(self.jid_list)-1
123 self.update() 131 self.update()
124 132
125 def update(self): 133 def update(self):
126 """redraw all the window""" 134 """redraw all the window"""
127 if self.isHidden(): 135 if self.isHidden():
128 return 136 return
129 Window.update(self) 137 Window.update(self)
130 viewList=[] 138 self.jid_list.sort()
131 for jid in self.jid_ids:
132 viewList.append(self.jid_ids[jid])
133 viewList.sort()
134 begin=0 if self.__index<self.rHeight else self.__index-self.rHeight+1 139 begin=0 if self.__index<self.rHeight else self.__index-self.rHeight+1
135 idx=0 140 idx=0
136 for item in viewList[begin:self.rHeight+begin]: 141 for item in self.jid_list[begin:self.rHeight+begin]:
137 attr = curses.A_REVERSE if ( self.isActive() and (idx+begin) == self.__index ) else 0 142 attr = curses.A_REVERSE if ( self.isActive() and (idx+begin) == self.__index ) else 0
138 centered = item.center(self.rWidth) ## it's nicer in the center :) 143 centered = item.center(self.rWidth) ## it's nicer in the center :)
139 self.addYXStr(idx, 0, centered, attr) 144 self.addYXStr(idx, 0, centered, attr)
140 idx = idx + 1 145 idx = idx + 1
141 146
145 if k == curses.KEY_UP: 150 if k == curses.KEY_UP:
146 self.indexDown() 151 self.indexDown()
147 elif k == curses.KEY_DOWN: 152 elif k == curses.KEY_DOWN:
148 self.indexUp() 153 self.indexUp()
149 elif k == ascii.NL: 154 elif k == ascii.NL:
150 if not self.jid_ids: 155 if not self.jid_list:
151 return 156 return
152 try: 157 try:
153 self.__enterCB(self.jid_ids.keys()[self.__index]) 158 self.__enterCB(self.jid_list[self.__index])
154 except NameError: 159 except NameError:
155 pass # TODO: thrown an error here 160 pass # TODO: thrown an error here
156 161
157 class SortilegeApp(QuickApp): 162 class SortilegeApp(QuickApp):
158 163
168 ## main loop setup ## 173 ## main loop setup ##
169 self.loop=gobject.MainLoop() 174 self.loop=gobject.MainLoop()
170 gobject.io_add_watch(0, gobject.IO_IN, self.loopCB) 175 gobject.io_add_watch(0, gobject.IO_IN, self.loopCB)
171 176
172 ## misc init stuff ## 177 ## misc init stuff ##
178 self.CM = QuickContactManagement()
173 self.listWins=[] 179 self.listWins=[]
174 self.chatParams={'timestamp':True, 180 self.chatParams={'timestamp':True,
175 'color':True, 181 'color':True,
176 'short_nick':False} 182 'short_nick':False}
177 183
188 194
189 ## colours ## 195 ## colours ##
190 self.color(True) 196 self.color(True)
191 197
192 ## windows ## 198 ## windows ##
193 self.contactList = ContactList() 199 self.contactList = ContactList(self, self.CM)
194 self.editBar = EditBox(stdscr, "> ", self.code) 200 self.editBar = EditBox(stdscr, "> ", self.code)
195 self.editBar.activate(False) 201 self.editBar.activate(False)
196 self.statusBar = StatusBar(stdscr, self.code) 202 self.statusBar = StatusBar(stdscr, self.code)
197 self.statusBar.hide(True) 203 self.statusBar.hide(True)
198 self.addWin(self.contactList) 204 self.addWin(self.contactList)
235 241
236 242
237 def showChat(self, chat): 243 def showChat(self, chat):
238 debug ("show chat") 244 debug ("show chat")
239 if self.currentChat: 245 if self.currentChat:
240 debug ("hide de %s", self.currentChat) 246 debug ("hiding %s", self.currentChat)
241 self.chat_wins[self.currentChat].hide() 247 self.chat_wins[self.currentChat].hide()
242 self.currentChat=chat 248 self.currentChat=chat
243 debug ("show de %s", self.currentChat) 249 debug ("showing %s", self.currentChat)
244 self.chat_wins[self.currentChat].show() 250 self.chat_wins[self.currentChat].show()
245 self.chat_wins[self.currentChat].update() 251 self.chat_wins[self.currentChat].update()
246 252
247 253
248 ### EVENTS ### 254 ### EVENTS ###
266 if type==question: 272 if type==question:
267 raise NotImplementedError 273 raise NotImplementedError
268 pass 274 pass
269 275
270 276
271 def presenceUpdate(self, jabber_id, type, show, status, priority): 277 def presenceUpdate(self, jabber_id, show, priority, statuses):
272 QuickApp.presenceUpdate(self, jabber_id, type, show, status, priority) 278 QuickApp.presenceUpdate(self, jabber_id, show, priority, statuses)
273 self.editBar.replace_cur() 279 self.editBar.replace_cur()
274 curses.doupdate() 280 curses.doupdate()
275 281
276 def askConfirmation(self, type, id, data): 282 def askConfirmation(self, type, id, data):
277 #FIXME 283 #FIXME