comparison sat_frontends/primitivus/base.py @ 4037:524856bd7b19

massive refactoring to switch from camelCase to snake_case: historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a pre-PEP8 code, to use the same coding style as in Twisted. However, snake_case is more readable and it's better to follow PEP8 best practices, so it has been decided to move on full snake_case. Because Libervia has a huge codebase, this ended with a ugly mix of camelCase and snake_case. To fix that, this patch does a big refactoring by renaming every function and method (including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case. This is a massive change, and may result in some bugs.
author Goffi <goffi@goffi.org>
date Sat, 08 Apr 2023 13:54:42 +0200
parents b5bed164dce0
children 4b842c1fb686
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
18 18
19 19
20 from sat.core.i18n import _, D_ 20 from sat.core.i18n import _, D_
21 from sat_frontends.primitivus.constants import Const as C 21 from sat_frontends.primitivus.constants import Const as C
22 from sat.core import log_config 22 from sat.core import log_config
23 log_config.satConfigure(C.LOG_BACKEND_STANDARD, C) 23 log_config.sat_configure(C.LOG_BACKEND_STANDARD, C)
24 from sat.core import log as logging 24 from sat.core import log as logging
25 log = logging.getLogger(__name__) 25 log = logging.getLogger(__name__)
26 from sat.tools import config as sat_config 26 from sat.tools import config as sat_config
27 import urwid 27 import urwid
28 from urwid.util import is_wide_char 28 from urwid.util import is_wide_char
43 from sat_frontends.tools import jid 43 from sat_frontends.tools import jid
44 import signal 44 import signal
45 import sys 45 import sys
46 ## bridge handling 46 ## bridge handling
47 # we get bridge name from conf and initialise the right class accordingly 47 # we get bridge name from conf and initialise the right class accordingly
48 main_config = sat_config.parseMainConf() 48 main_config = sat_config.parse_main_conf()
49 bridge_name = sat_config.getConfig(main_config, '', 'bridge', 'dbus') 49 bridge_name = sat_config.config_get(main_config, '', 'bridge', 'dbus')
50 if 'dbus' not in bridge_name: 50 if 'dbus' not in bridge_name:
51 print(u"only D-Bus bridge is currently supported") 51 print(u"only D-Bus bridge is currently supported")
52 sys.exit(3) 52 sys.exit(3)
53 53
54 54
61 modes = {None: (C.MODE_NORMAL, u''), 61 modes = {None: (C.MODE_NORMAL, u''),
62 a_key['MODE_INSERTION']: (C.MODE_INSERTION, u'> '), 62 a_key['MODE_INSERTION']: (C.MODE_INSERTION, u'> '),
63 a_key['MODE_COMMAND']: (C.MODE_COMMAND, u':')} #XXX: captions *MUST* be unicode 63 a_key['MODE_COMMAND']: (C.MODE_COMMAND, u':')} #XXX: captions *MUST* be unicode
64 super(EditBar, self).__init__(modes) 64 super(EditBar, self).__init__(modes)
65 self.host = host 65 self.host = host
66 self.setCompletionMethod(self._text_completion) 66 self.set_completion_method(self._text_completion)
67 urwid.connect_signal(self, 'click', self.onTextEntered) 67 urwid.connect_signal(self, 'click', self.on_text_entered)
68 68
69 def _text_completion(self, text, completion_data, mode): 69 def _text_completion(self, text, completion_data, mode):
70 if mode == C.MODE_INSERTION: 70 if mode == C.MODE_INSERTION:
71 if self.host.selected_widget is not None: 71 if self.host.selected_widget is not None:
72 try: 72 try:
76 else: 76 else:
77 return completion(text, completion_data) 77 return completion(text, completion_data)
78 else: 78 else:
79 return text 79 return text
80 80
81 def onTextEntered(self, editBar): 81 def on_text_entered(self, editBar):
82 """Called when text is entered in the main edit bar""" 82 """Called when text is entered in the main edit bar"""
83 if self.mode == C.MODE_INSERTION: 83 if self.mode == C.MODE_INSERTION:
84 if isinstance(self.host.selected_widget, quick_chat.QuickChat): 84 if isinstance(self.host.selected_widget, quick_chat.QuickChat):
85 chat_widget = self.host.selected_widget 85 chat_widget = self.host.selected_widget
86 self.host.messageSend( 86 self.host.message_send(
87 chat_widget.target, 87 chat_widget.target,
88 {'': editBar.get_edit_text()}, # TODO: handle language 88 {'': editBar.get_edit_text()}, # TODO: handle language
89 mess_type = C.MESS_TYPE_GROUPCHAT if chat_widget.type == C.CHAT_GROUP else C.MESS_TYPE_CHAT, # TODO: put this in QuickChat 89 mess_type = C.MESS_TYPE_GROUPCHAT if chat_widget.type == C.CHAT_GROUP else C.MESS_TYPE_CHAT, # TODO: put this in QuickChat
90 errback=lambda failure: self.host.showDialog(_("Error while sending message ({})").format(failure), type="error"), 90 errback=lambda failure: self.host.show_dialog(_("Error while sending message ({})").format(failure), type="error"),
91 profile_key=chat_widget.profile 91 profile_key=chat_widget.profile
92 ) 92 )
93 editBar.set_edit_text('') 93 editBar.set_edit_text('')
94 elif self.mode == C.MODE_COMMAND: 94 elif self.mode == C.MODE_COMMAND:
95 self.commandHandler() 95 self.command_handler()
96 96
97 def commandHandler(self): 97 def command_handler(self):
98 #TODO: separate class with auto documentation (with introspection) 98 #TODO: separate class with auto documentation (with introspection)
99 # and completion method 99 # and completion method
100 tokens = self.get_edit_text().split(' ') 100 tokens = self.get_edit_text().split(' ')
101 command, args = tokens[0], tokens[1:] 101 command, args = tokens[0], tokens[1:]
102 if command == 'quit': 102 if command == 'quit':
103 self.host.onExit() 103 self.host.on_exit()
104 raise urwid.ExitMainLoop() 104 raise urwid.ExitMainLoop()
105 elif command == 'messages': 105 elif command == 'messages':
106 wid = sat_widgets.GenericList(logging.memoryGet()) 106 wid = sat_widgets.GenericList(logging.memory_get())
107 self.host.selectWidget(wid) 107 self.host.select_widget(wid)
108 # FIXME: reactivate the command 108 # FIXME: reactivate the command
109 # elif command == 'presence': 109 # elif command == 'presence':
110 # values = [value for value in commonConst.PRESENCE.keys()] 110 # values = [value for value in commonConst.PRESENCE.keys()]
111 # values = [value if value else 'online' for value in values] # the empty value actually means 'online' 111 # values = [value if value else 'online' for value in values] # the empty value actually means 'online'
112 # if args and args[0] in values: 112 # if args and args[0] in values:
113 # presence = '' if args[0] == 'online' else args[0] 113 # presence = '' if args[0] == 'online' else args[0]
114 # self.host.status_bar.onChange(user_data=sat_widgets.ClickableText(commonConst.PRESENCE[presence])) 114 # self.host.status_bar.on_change(user_data=sat_widgets.ClickableText(commonConst.PRESENCE[presence]))
115 # else: 115 # else:
116 # self.host.status_bar.onPresenceClick() 116 # self.host.status_bar.on_presence_click()
117 # elif command == 'status': 117 # elif command == 'status':
118 # if args: 118 # if args:
119 # self.host.status_bar.onChange(user_data=sat_widgets.AdvancedEdit(args[0])) 119 # self.host.status_bar.on_change(user_data=sat_widgets.AdvancedEdit(args[0]))
120 # else: 120 # else:
121 # self.host.status_bar.onStatusClick() 121 # self.host.status_bar.on_status_click()
122 elif command == 'history': 122 elif command == 'history':
123 widget = self.host.selected_widget 123 widget = self.host.selected_widget
124 if isinstance(widget, quick_chat.QuickChat): 124 if isinstance(widget, quick_chat.QuickChat):
125 try: 125 try:
126 limit = int(args[0]) 126 limit = int(args[0])
127 except (IndexError, ValueError): 127 except (IndexError, ValueError):
128 limit = 50 128 limit = 50
129 widget.updateHistory(size=limit, profile=widget.profile) 129 widget.update_history(size=limit, profile=widget.profile)
130 elif command == 'search': 130 elif command == 'search':
131 widget = self.host.selected_widget 131 widget = self.host.selected_widget
132 if isinstance(widget, quick_chat.QuickChat): 132 if isinstance(widget, quick_chat.QuickChat):
133 pattern = " ".join(args) 133 pattern = " ".join(args)
134 if not pattern: 134 if not pattern:
135 self.host.notif_bar.addMessage(D_("Please specify the globbing pattern to search for")) 135 self.host.notif_bar.add_message(D_("Please specify the globbing pattern to search for"))
136 else: 136 else:
137 widget.updateHistory(size=C.HISTORY_LIMIT_NONE, filters={'search': pattern}, profile=widget.profile) 137 widget.update_history(size=C.HISTORY_LIMIT_NONE, filters={'search': pattern}, profile=widget.profile)
138 elif command == 'filter': 138 elif command == 'filter':
139 # FIXME: filter is now only for current widget, 139 # FIXME: filter is now only for current widget,
140 # need to be able to set it globally or per widget 140 # need to be able to set it globally or per widget
141 widget = self.host.selected_widget 141 widget = self.host.selected_widget
142 # FIXME: Q&D way, need to be more generic 142 # FIXME: Q&D way, need to be more generic
143 if isinstance(widget, quick_chat.QuickChat): 143 if isinstance(widget, quick_chat.QuickChat):
144 widget.setFilter(args) 144 widget.set_filter(args)
145 elif command in ('topic', 'suject', 'title'): 145 elif command in ('topic', 'suject', 'title'):
146 try: 146 try:
147 new_title = args[0].strip() 147 new_title = args[0].strip()
148 except IndexError: 148 except IndexError:
149 new_title = None 149 new_title = None
150 widget = self.host.selected_widget 150 widget = self.host.selected_widget
151 if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP: 151 if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP:
152 widget.onSubjectDialog(new_title) 152 widget.on_subject_dialog(new_title)
153 else: 153 else:
154 return 154 return
155 self.set_edit_text('') 155 self.set_edit_text('')
156 156
157 def _historyCb(self, text): 157 def _history_cb(self, text):
158 self.set_edit_text(text) 158 self.set_edit_text(text)
159 self.set_edit_pos(len(text)) 159 self.set_edit_pos(len(text))
160 160
161 def keypress(self, size, key): 161 def keypress(self, size, key):
162 """Callback when a key is pressed. Send "composing" states 162 """Callback when a key is pressed. Send "composing" states
163 and move the index of the temporary history stack.""" 163 and move the index of the temporary history stack."""
164 if key == a_key['MODAL_ESCAPE']: 164 if key == a_key['MODAL_ESCAPE']:
165 # first save the text to the current mode, then change to NORMAL 165 # first save the text to the current mode, then change to NORMAL
166 self.host._updateInputHistory(self.get_edit_text(), mode=self.mode) 166 self.host._update_input_history(self.get_edit_text(), mode=self.mode)
167 self.host._updateInputHistory(mode=C.MODE_NORMAL) 167 self.host._update_input_history(mode=C.MODE_NORMAL)
168 if self._mode == C.MODE_NORMAL and key in self._modes: 168 if self._mode == C.MODE_NORMAL and key in self._modes:
169 self.host._updateInputHistory(mode=self._modes[key][0]) 169 self.host._update_input_history(mode=self._modes[key][0])
170 if key == a_key['HISTORY_PREV']: 170 if key == a_key['HISTORY_PREV']:
171 self.host._updateInputHistory(self.get_edit_text(), -1, self._historyCb, self.mode) 171 self.host._update_input_history(self.get_edit_text(), -1, self._history_cb, self.mode)
172 return 172 return
173 elif key == a_key['HISTORY_NEXT']: 173 elif key == a_key['HISTORY_NEXT']:
174 self.host._updateInputHistory(self.get_edit_text(), +1, self._historyCb, self.mode) 174 self.host._update_input_history(self.get_edit_text(), +1, self._history_cb, self.mode)
175 return 175 return
176 elif key == a_key['EDIT_ENTER']: 176 elif key == a_key['EDIT_ENTER']:
177 self.host._updateInputHistory(self.get_edit_text(), mode=self.mode) 177 self.host._update_input_history(self.get_edit_text(), mode=self.mode)
178 else: 178 else:
179 if (self._mode == C.MODE_INSERTION 179 if (self._mode == C.MODE_INSERTION
180 and isinstance(self.host.selected_widget, quick_chat.QuickChat) 180 and isinstance(self.host.selected_widget, quick_chat.QuickChat)
181 and key not in sat_widgets.FOCUS_KEYS 181 and key not in sat_widgets.FOCUS_KEYS
182 and key not in (a_key['HISTORY_PREV'], a_key['HISTORY_NEXT']) 182 and key not in (a_key['HISTORY_PREV'], a_key['HISTORY_NEXT'])
183 and self.host.sync): 183 and self.host.sync):
184 self.host.bridge.chatStateComposing(self.host.selected_widget.target, self.host.selected_widget.profile) 184 self.host.bridge.chat_state_composing(self.host.selected_widget.target, self.host.selected_widget.profile)
185 185
186 return super(EditBar, self).keypress(size, key) 186 return super(EditBar, self).keypress(size, key)
187 187
188 188
189 class PrimitivusTopWidget(sat_widgets.FocusPile): 189 class PrimitivusTopWidget(sat_widgets.FocusPile):
201 self._focus_extra = False 201 self._focus_extra = False
202 super(PrimitivusTopWidget, self).__init__([('pack', self._menu), self._body, ('pack', self._edit_bar)]) 202 super(PrimitivusTopWidget, self).__init__([('pack', self._menu), self._body, ('pack', self._edit_bar)])
203 for position in self.positions: 203 for position in self.positions:
204 setattr(self, 204 setattr(self,
205 position, 205 position,
206 property(lambda: self, self.widgetGet(position=position), 206 property(lambda: self, self.widget_get(position=position),
207 lambda pos, new_wid: self.widgetSet(new_wid, position=pos)) 207 lambda pos, new_wid: self.widget_set(new_wid, position=pos))
208 ) 208 )
209 self.focus_position = len(self.contents)-1 209 self.focus_position = len(self.contents)-1
210 210
211 def getVisiblePositions(self, keep=None): 211 def get_visible_positions(self, keep=None):
212 """Return positions that are not hidden in the right order 212 """Return positions that are not hidden in the right order
213 213
214 @param keep: if not None, this position will be keep in the right order, even if it's hidden 214 @param keep: if not None, this position will be keep in the right order, even if it's hidden
215 (can be useful to find its index) 215 (can be useful to find its index)
216 @return (list): list of visible positions 216 @return (list): list of visible positions
239 return super(PrimitivusTopWidget, self).keypress(size, key) 239 return super(PrimitivusTopWidget, self).keypress(size, key)
240 240
241 if focus in self._hidden: 241 if focus in self._hidden:
242 return 242 return
243 243
244 self.focus_position = self.getVisiblePositions().index(focus) 244 self.focus_position = self.get_visible_positions().index(focus)
245 return 245 return
246 246
247 return super(PrimitivusTopWidget, self).keypress(size, key) 247 return super(PrimitivusTopWidget, self).keypress(size, key)
248 248
249 def widgetGet(self, position): 249 def widget_get(self, position):
250 if not position in self.positions: 250 if not position in self.positions:
251 raise ValueError("Unknown position {}".format(position)) 251 raise ValueError("Unknown position {}".format(position))
252 return getattr(self, "_{}".format(position)) 252 return getattr(self, "_{}".format(position))
253 253
254 def widgetSet(self, widget, position): 254 def widget_set(self, widget, position):
255 if not position in self.positions: 255 if not position in self.positions:
256 raise ValueError("Unknown position {}".format(position)) 256 raise ValueError("Unknown position {}".format(position))
257 return setattr(self, "_{}".format(position), widget) 257 return setattr(self, "_{}".format(position), widget)
258 258
259 def hideSwitch(self, position): 259 def hide_switch(self, position):
260 if not position in self.can_hide: 260 if not position in self.can_hide:
261 raise ValueError("Can't switch position {}".format(position)) 261 raise ValueError("Can't switch position {}".format(position))
262 hide = not position in self._hidden 262 hide = not position in self._hidden
263 widget = self.widgetGet(position) 263 widget = self.widget_get(position)
264 idx = self.getVisiblePositions(position).index(position) 264 idx = self.get_visible_positions(position).index(position)
265 if hide: 265 if hide:
266 del self.contents[idx] 266 del self.contents[idx]
267 self._hidden.add(position) 267 self._hidden.add(position)
268 else: 268 else:
269 self.contents.insert(idx, (widget, ('pack', None))) 269 self.contents.insert(idx, (widget, ('pack', None)))
270 self._hidden.remove(position) 270 self._hidden.remove(position)
271 271
272 def show(self, position): 272 def show(self, position):
273 if position in self._hidden: 273 if position in self._hidden:
274 self.hideSwitch(position) 274 self.hide_switch(position)
275 275
276 def hide(self, position): 276 def hide(self, position):
277 if not position in self._hidden: 277 if not position in self._hidden:
278 self.hideSwitch(position) 278 self.hide_switch(position)
279 279
280 280
281 class PrimitivusApp(QuickApp, InputHistory): 281 class PrimitivusApp(QuickApp, InputHistory):
282 MB_HANDLER = False 282 MB_HANDLER = False
283 AVATARS_HANDLER = False 283 AVATARS_HANDLER = False
287 if bridge_module is None: 287 if bridge_module is None:
288 log.error(u"Can't import {} bridge".format(bridge_name)) 288 log.error(u"Can't import {} bridge".format(bridge_name))
289 sys.exit(3) 289 sys.exit(3)
290 else: 290 else:
291 log.debug(u"Loading {} bridge".format(bridge_name)) 291 log.debug(u"Loading {} bridge".format(bridge_name))
292 QuickApp.__init__(self, bridge_factory=bridge_module.Bridge, xmlui=xmlui, check_options=quick_utils.check_options, connect_bridge=False) 292 QuickApp.__init__(self, bridge_factory=bridge_module.bridge, xmlui=xmlui, check_options=quick_utils.check_options, connect_bridge=False)
293 ## main loop setup ## 293 ## main loop setup ##
294 event_loop = urwid.GLibEventLoop if 'dbus' in bridge_name else urwid.TwistedEventLoop 294 event_loop = urwid.GLibEventLoop if 'dbus' in bridge_name else urwid.TwistedEventLoop
295 self.loop = urwid.MainLoop(urwid.SolidFill(), C.PALETTE, event_loop=event_loop(), input_filter=self.inputFilter, unhandled_input=self.keyHandler) 295 self.loop = urwid.MainLoop(urwid.SolidFill(), C.PALETTE, event_loop=event_loop(), input_filter=self.input_filter, unhandled_input=self.key_handler)
296 296
297 @classmethod 297 @classmethod
298 def run(cls): 298 def run(cls):
299 cls().start() 299 cls().start()
300 300
301 def onBridgeConnected(self): 301 def on_bridge_connected(self):
302 302
303 ##misc setup## 303 ##misc setup##
304 self._visible_widgets = set() 304 self._visible_widgets = set()
305 self.notif_bar = sat_widgets.NotificationBar() 305 self.notif_bar = sat_widgets.NotificationBar()
306 urwid.connect_signal(self.notif_bar, 'change', self.onNotification) 306 urwid.connect_signal(self.notif_bar, 'change', self.on_notification)
307 307
308 self.progress_wid = self.widgets.getOrCreateWidget(Progress, None, on_new_widget=None) 308 self.progress_wid = self.widgets.get_or_create_widget(Progress, None, on_new_widget=None)
309 urwid.connect_signal(self.notif_bar.progress, 'click', lambda x: self.selectWidget(self.progress_wid)) 309 urwid.connect_signal(self.notif_bar.progress, 'click', lambda x: self.select_widget(self.progress_wid))
310 self.__saved_overlay = None 310 self.__saved_overlay = None
311 311
312 self.x_notify = Notify() 312 self.x_notify = Notify()
313 313
314 # we already manage exit with a_key['APP_QUIT'], so we don't want C-c 314 # we already manage exit with a_key['APP_QUIT'], so we don't want C-c
315 signal.signal(signal.SIGINT, signal.SIG_IGN) 315 signal.signal(signal.SIGINT, signal.SIG_IGN)
316 sat_conf = sat_config.parseMainConf() 316 sat_conf = sat_config.parse_main_conf()
317 self._bracketed_paste = C.bool( 317 self._bracketed_paste = C.bool(
318 sat_config.getConfig(sat_conf, C.CONFIG_SECTION, 'bracketed_paste', 'false') 318 sat_config.config_get(sat_conf, C.CONFIG_SECTION, 'bracketed_paste', 'false')
319 ) 319 )
320 if self._bracketed_paste: 320 if self._bracketed_paste:
321 log.debug("setting bracketed paste mode as requested") 321 log.debug("setting bracketed paste mode as requested")
322 sys.stdout.write("\033[?2004h") 322 sys.stdout.write("\033[?2004h")
323 self._bracketed_mode_set = True 323 self._bracketed_mode_set = True
324 324
325 self.loop.widget = self.main_widget = ProfileManager(self) 325 self.loop.widget = self.main_widget = ProfileManager(self)
326 self.postInit() 326 self.post_init()
327 327
328 @property 328 @property
329 def visible_widgets(self): 329 def visible_widgets(self):
330 return self._visible_widgets 330 return self._visible_widgets
331 331
335 335
336 @mode.setter 336 @mode.setter
337 def mode(self, value): 337 def mode(self, value):
338 self.editBar.mode = value 338 self.editBar.mode = value
339 339
340 def modeHint(self, value): 340 def mode_hint(self, value):
341 """Change mode if make sens (i.e.: if there is nothing in the editBar)""" 341 """Change mode if make sens (i.e.: if there is nothing in the editBar)"""
342 if not self.editBar.get_edit_text(): 342 if not self.editBar.get_edit_text():
343 self.mode = value 343 self.mode = value
344 344
345 def debug(self): 345 def debug(self):
364 self.loop.draw_screen() 364 self.loop.draw_screen()
365 except AttributeError: 365 except AttributeError:
366 pass 366 pass
367 367
368 def start(self): 368 def start(self):
369 self.connectBridge() 369 self.connect_bridge()
370 self.loop.run() 370 self.loop.run()
371 371
372 def postInit(self): 372 def post_init(self):
373 try: 373 try:
374 config.applyConfig(self) 374 config.apply_config(self)
375 except Exception as e: 375 except Exception as e:
376 log.error(u"configuration error: {}".format(e)) 376 log.error(u"configuration error: {}".format(e))
377 popup = self.alert(_(u"Configuration Error"), _(u"Something went wrong while reading the configuration, please check :messages")) 377 popup = self.alert(_(u"Configuration Error"), _(u"Something went wrong while reading the configuration, please check :messages"))
378 if self.options.profile: 378 if self.options.profile:
379 self._early_popup = popup 379 self._early_popup = popup
380 else: 380 else:
381 self.showPopUp(popup) 381 self.show_pop_up(popup)
382 super(PrimitivusApp, self).postInit(self.main_widget) 382 super(PrimitivusApp, self).post_init(self.main_widget)
383 383
384 def keysToText(self, keys): 384 def keys_to_text(self, keys):
385 """Generator return normal text from urwid keys""" 385 """Generator return normal text from urwid keys"""
386 for k in keys: 386 for k in keys:
387 if k == 'tab': 387 if k == 'tab':
388 yield u'\t' 388 yield u'\t'
389 elif k == 'enter': 389 elif k == 'enter':
390 yield u'\n' 390 yield u'\n'
391 elif is_wide_char(k,0) or (len(k)==1 and ord(k) >= 32): 391 elif is_wide_char(k,0) or (len(k)==1 and ord(k) >= 32):
392 yield k 392 yield k
393 393
394 def inputFilter(self, input_, raw): 394 def input_filter(self, input_, raw):
395 if self.__saved_overlay and input_ != a_key['OVERLAY_HIDE']: 395 if self.__saved_overlay and input_ != a_key['OVERLAY_HIDE']:
396 return 396 return
397 397
398 ## paste detection/handling 398 ## paste detection/handling
399 if (len(input_) > 1 and # XXX: it may be needed to increase this value if buffer 399 if (len(input_) > 1 and # XXX: it may be needed to increase this value if buffer
437 extra.extend(input_) 437 extra.extend(input_)
438 else: 438 else:
439 if self.main_widget.focus == edit_bar: 439 if self.main_widget.focus == edit_bar:
440 # XXX: if a paste is detected, we append it directly to the edit bar text 440 # XXX: if a paste is detected, we append it directly to the edit bar text
441 # so the user can check it and press [enter] if it's OK 441 # so the user can check it and press [enter] if it's OK
442 buf_paste = u''.join(self.keysToText(input_)) 442 buf_paste = u''.join(self.keys_to_text(input_))
443 pos = edit_bar.edit_pos 443 pos = edit_bar.edit_pos
444 edit_bar.set_edit_text(u'{}{}{}'.format(edit_bar.edit_text[:pos], buf_paste, edit_bar.edit_text[pos:])) 444 edit_bar.set_edit_text(u'{}{}{}'.format(edit_bar.edit_text[:pos], buf_paste, edit_bar.edit_text[pos:]))
445 edit_bar.edit_pos+=len(buf_paste) 445 edit_bar.edit_pos+=len(buf_paste)
446 else: 446 else:
447 # we are not on the edit_bar, 447 # we are not on the edit_bar,
461 input_[input_.index(i)] = a_key['HISTORY_PREV'] 461 input_[input_.index(i)] = a_key['HISTORY_PREV']
462 if i[1] == 5: #Mouse wheel down 462 if i[1] == 5: #Mouse wheel down
463 input_[input_.index(i)] = a_key['HISTORY_NEXT'] 463 input_[input_.index(i)] = a_key['HISTORY_NEXT']
464 return input_ 464 return input_
465 465
466 def keyHandler(self, input_): 466 def key_handler(self, input_):
467 if input_ == a_key['MENU_HIDE']: 467 if input_ == a_key['MENU_HIDE']:
468 """User want to (un)hide the menu roller""" 468 """User want to (un)hide the menu roller"""
469 try: 469 try:
470 self.main_widget.hideSwitch('menu') 470 self.main_widget.hide_switch('menu')
471 except AttributeError: 471 except AttributeError:
472 pass 472 pass
473 elif input_ == a_key['NOTIFICATION_NEXT']: 473 elif input_ == a_key['NOTIFICATION_NEXT']:
474 """User wants to see next notification""" 474 """User wants to see next notification"""
475 self.notif_bar.showNext() 475 self.notif_bar.show_next()
476 elif input_ == a_key['OVERLAY_HIDE']: 476 elif input_ == a_key['OVERLAY_HIDE']:
477 """User wants to (un)hide overlay window""" 477 """User wants to (un)hide overlay window"""
478 if isinstance(self.loop.widget,urwid.Overlay): 478 if isinstance(self.loop.widget,urwid.Overlay):
479 self.__saved_overlay = self.loop.widget 479 self.__saved_overlay = self.loop.widget
480 self.loop.widget = self.main_widget 480 self.loop.widget = self.main_widget
481 else: 481 else:
482 if self.__saved_overlay: 482 if self.__saved_overlay:
483 self.loop.widget = self.__saved_overlay 483 self.loop.widget = self.__saved_overlay
484 self.__saved_overlay = None 484 self.__saved_overlay = None
485 485
486 elif input_ == a_key['DEBUG'] and 'D' in self.bridge.getVersion(): #Debug only for dev versions 486 elif input_ == a_key['DEBUG'] and 'D' in self.bridge.version_get(): #Debug only for dev versions
487 self.debug() 487 self.debug()
488 elif input_ == a_key['CONTACTS_HIDE']: #user wants to (un)hide the contact lists 488 elif input_ == a_key['CONTACTS_HIDE']: #user wants to (un)hide the contact lists
489 try: 489 try:
490 for wid, options in self.center_part.contents: 490 for wid, options in self.center_part.contents:
491 if self.contact_lists_pile is wid: 491 if self.contact_lists_pile is wid:
505 else: 505 else:
506 if 'save_main_widget' in dir(self): 506 if 'save_main_widget' in dir(self):
507 self.loop.widget = self.save_main_widget 507 self.loop.widget = self.save_main_widget
508 del self.save_main_widget 508 del self.save_main_widget
509 try: 509 try:
510 return self.menu_roller.checkShortcuts(input_) 510 return self.menu_roller.check_shortcuts(input_)
511 except AttributeError: 511 except AttributeError:
512 return input_ 512 return input_
513 513
514 def addMenus(self, menu, type_filter, menu_data=None): 514 def add_menus(self, menu, type_filter, menu_data=None):
515 """Add cached menus to instance 515 """Add cached menus to instance
516 @param menu: sat_widgets.Menu instance 516 @param menu: sat_widgets.Menu instance
517 @param type_filter: menu type like is sat.core.sat_main.importMenu 517 @param type_filter: menu type like is sat.core.sat_main.import_menu
518 @param menu_data: data to send with these menus 518 @param menu_data: data to send with these menus
519 519
520 """ 520 """
521 def add_menu_cb(callback_id): 521 def add_menu_cb(callback_id):
522 self.launchAction(callback_id, menu_data, profile=self.current_profile) 522 self.action_launch(callback_id, menu_data, profile=self.current_profile)
523 for id_, type_, path, path_i18n, extra in self.bridge.menusGet("", C.NO_SECURITY_LIMIT ): # TODO: manage extra 523 for id_, type_, path, path_i18n, extra in self.bridge.menus_get("", C.NO_SECURITY_LIMIT ): # TODO: manage extra
524 if type_ != type_filter: 524 if type_ != type_filter:
525 continue 525 continue
526 if len(path) != 2: 526 if len(path) != 2:
527 raise NotImplementedError("Menu with a path != 2 are not implemented yet") 527 raise NotImplementedError("Menu with a path != 2 are not implemented yet")
528 menu.addMenu(path_i18n[0], path_i18n[1], lambda dummy,id_=id_: add_menu_cb(id_)) 528 menu.add_menu(path_i18n[0], path_i18n[1], lambda dummy,id_=id_: add_menu_cb(id_))
529 529
530 530
531 def _buildMenuRoller(self): 531 def _build_menu_roller(self):
532 menu = sat_widgets.Menu(self.loop) 532 menu = sat_widgets.Menu(self.loop)
533 general = _("General") 533 general = _("General")
534 menu.addMenu(general, _("Connect"), self.onConnectRequest) 534 menu.add_menu(general, _("Connect"), self.on_connect_request)
535 menu.addMenu(general, _("Disconnect"), self.onDisconnectRequest) 535 menu.add_menu(general, _("Disconnect"), self.on_disconnect_request)
536 menu.addMenu(general, _("Parameters"), self.onParam) 536 menu.add_menu(general, _("Parameters"), self.on_param)
537 menu.addMenu(general, _("About"), self.onAboutRequest) 537 menu.add_menu(general, _("About"), self.on_about_request)
538 menu.addMenu(general, _("Exit"), self.onExitRequest, a_key['APP_QUIT']) 538 menu.add_menu(general, _("Exit"), self.on_exit_request, a_key['APP_QUIT'])
539 menu.addMenu(_("Contacts")) # add empty menu to save the place in the menu order 539 menu.add_menu(_("Contacts")) # add empty menu to save the place in the menu order
540 groups = _("Groups") 540 groups = _("Groups")
541 menu.addMenu(groups) 541 menu.add_menu(groups)
542 menu.addMenu(groups, _("Join room"), self.onJoinRoomRequest, a_key['ROOM_JOIN']) 542 menu.add_menu(groups, _("Join room"), self.on_join_room_request, a_key['ROOM_JOIN'])
543 #additionals menus 543 #additionals menus
544 #FIXME: do this in a more generic way (in quickapp) 544 #FIXME: do this in a more generic way (in quickapp)
545 self.addMenus(menu, C.MENU_GLOBAL) 545 self.add_menus(menu, C.MENU_GLOBAL)
546 546
547 menu_roller = sat_widgets.MenuRoller([(_('Main menu'), menu, C.MENU_ID_MAIN)]) 547 menu_roller = sat_widgets.MenuRoller([(_('Main menu'), menu, C.MENU_ID_MAIN)])
548 return menu_roller 548 return menu_roller
549 549
550 def _buildMainWidget(self): 550 def _build_main_widget(self):
551 self.contact_lists_pile = urwid.Pile([]) 551 self.contact_lists_pile = urwid.Pile([])
552 #self.center_part = urwid.Columns([('weight',2,self.contact_lists[profile]),('weight',8,Chat('',self))]) 552 #self.center_part = urwid.Columns([('weight',2,self.contact_lists[profile]),('weight',8,Chat('',self))])
553 self.center_part = urwid.Columns([('weight', 2, self.contact_lists_pile), ('weight', 8, urwid.Filler(urwid.Text('')))]) 553 self.center_part = urwid.Columns([('weight', 2, self.contact_lists_pile), ('weight', 8, urwid.Filler(urwid.Text('')))])
554 554
555 self.editBar = EditBar(self) 555 self.editBar = EditBar(self)
556 self.menu_roller = self._buildMenuRoller() 556 self.menu_roller = self._build_menu_roller()
557 self.main_widget = PrimitivusTopWidget(self.center_part, self.menu_roller, self.notif_bar, self.editBar) 557 self.main_widget = PrimitivusTopWidget(self.center_part, self.menu_roller, self.notif_bar, self.editBar)
558 return self.main_widget 558 return self.main_widget
559 559
560 def plugging_profiles(self): 560 def plugging_profiles(self):
561 self.loop.widget = self._buildMainWidget() 561 self.loop.widget = self._build_main_widget()
562 self.redraw() 562 self.redraw()
563 try: 563 try:
564 # if a popup arrived before main widget is build, we need to show it now 564 # if a popup arrived before main widget is build, we need to show it now
565 self.showPopUp(self._early_popup) 565 self.show_pop_up(self._early_popup)
566 except AttributeError: 566 except AttributeError:
567 pass 567 pass
568 else: 568 else:
569 del self._early_popup 569 del self._early_popup
570 570
571 def profilePlugged(self, profile): 571 def profile_plugged(self, profile):
572 QuickApp.profilePlugged(self, profile) 572 QuickApp.profile_plugged(self, profile)
573 contact_list = self.widgets.getOrCreateWidget(ContactList, None, on_new_widget=None, on_click=self.contactSelected, on_change=lambda w: self.redraw(), profile=profile) 573 contact_list = self.widgets.get_or_create_widget(ContactList, None, on_new_widget=None, on_click=self.contact_selected, on_change=lambda w: self.redraw(), profile=profile)
574 self.contact_lists_pile.contents.append((contact_list, ('weight', 1))) 574 self.contact_lists_pile.contents.append((contact_list, ('weight', 1)))
575 return contact_list 575 return contact_list
576 576
577 def isHidden(self): 577 def is_hidden(self):
578 """Tells if the frontend window is hidden. 578 """Tells if the frontend window is hidden.
579 579
580 @return bool 580 @return bool
581 """ 581 """
582 return False # FIXME: implement when necessary 582 return False # FIXME: implement when necessary
588 @param title(unicode): title of the dialog 588 @param title(unicode): title of the dialog
589 @param message(unicode): body of the dialog 589 @param message(unicode): body of the dialog
590 @return (urwid_satext.Alert): the created Alert instance 590 @return (urwid_satext.Alert): the created Alert instance
591 """ 591 """
592 popup = sat_widgets.Alert(title, message) 592 popup = sat_widgets.Alert(title, message)
593 popup.setCallback('ok', lambda dummy: self.removePopUp(popup)) 593 popup.set_callback('ok', lambda dummy: self.remove_pop_up(popup))
594 self.showPopUp(popup, width=75, height=20) 594 self.show_pop_up(popup, width=75, height=20)
595 return popup 595 return popup
596 596
597 def removePopUp(self, widget=None): 597 def remove_pop_up(self, widget=None):
598 """Remove current pop-up, and if there is other in queue, show it 598 """Remove current pop-up, and if there is other in queue, show it
599 599
600 @param widget(None, urwid.Widget): if not None remove this popup from front or queue 600 @param widget(None, urwid.Widget): if not None remove this popup from front or queue
601 """ 601 """
602 # TODO: refactor popup management in a cleaner way 602 # TODO: refactor popup management in a cleaner way
605 if widget is not None and not isinstance(widget, urwid.Button): 605 if widget is not None and not isinstance(widget, urwid.Button):
606 if isinstance(self.loop.widget, urwid.Overlay): 606 if isinstance(self.loop.widget, urwid.Overlay):
607 current_popup = self.loop.widget.top_w 607 current_popup = self.loop.widget.top_w
608 if not current_popup == widget: 608 if not current_popup == widget:
609 try: 609 try:
610 self.notif_bar.removePopUp(widget) 610 self.notif_bar.remove_pop_up(widget)
611 except ValueError: 611 except ValueError:
612 log.warning(u"Trying to remove an unknown widget {}".format(widget)) 612 log.warning(u"Trying to remove an unknown widget {}".format(widget))
613 return 613 return
614 self.loop.widget = self.main_widget 614 self.loop.widget = self.main_widget
615 next_popup = self.notif_bar.getNextPopup() 615 next_popup = self.notif_bar.get_next_popup()
616 if next_popup: 616 if next_popup:
617 #we still have popup to show, we display it 617 #we still have popup to show, we display it
618 self.showPopUp(next_popup) 618 self.show_pop_up(next_popup)
619 else: 619 else:
620 self.redraw() 620 self.redraw()
621 621
622 def showPopUp(self, pop_up_widget, width=None, height=None, align='center', 622 def show_pop_up(self, pop_up_widget, width=None, height=None, align='center',
623 valign='middle'): 623 valign='middle'):
624 """Show a pop-up window if possible, else put it in queue 624 """Show a pop-up window if possible, else put it in queue
625 625
626 @param pop_up_widget: pop up to show 626 @param pop_up_widget: pop up to show
627 @param width(int, None): width of the popup 627 @param width(int, None): width of the popup
638 display_widget = urwid.Overlay( 638 display_widget = urwid.Overlay(
639 pop_up_widget, self.main_widget, align, width, valign, height) 639 pop_up_widget, self.main_widget, align, width, valign, height)
640 self.loop.widget = display_widget 640 self.loop.widget = display_widget
641 self.redraw() 641 self.redraw()
642 else: 642 else:
643 self.notif_bar.addPopUp(pop_up_widget) 643 self.notif_bar.add_pop_up(pop_up_widget)
644 644
645 def barNotify(self, message): 645 def bar_notify(self, message):
646 """"Notify message to user via notification bar""" 646 """"Notify message to user via notification bar"""
647 self.notif_bar.addMessage(message) 647 self.notif_bar.add_message(message)
648 self.redraw() 648 self.redraw()
649 649
650 def notify(self, type_, entity=None, message=None, subject=None, callback=None, cb_args=None, widget=None, profile=C.PROF_KEY_NONE): 650 def notify(self, type_, entity=None, message=None, subject=None, callback=None, cb_args=None, widget=None, profile=C.PROF_KEY_NONE):
651 if widget is None or widget is not None and widget != self.selected_widget: 651 if widget is None or widget is not None and widget != self.selected_widget:
652 # we ignore notification if the widget is selected but we can 652 # we ignore notification if the widget is selected but we can
653 # still do a desktop notification is the X window has not the focus 653 # still do a desktop notification is the X window has not the focus
654 super(PrimitivusApp, self).notify(type_, entity, message, subject, callback, cb_args, widget, profile) 654 super(PrimitivusApp, self).notify(type_, entity, message, subject, callback, cb_args, widget, profile)
655 # we don't want notifications without message on desktop 655 # we don't want notifications without message on desktop
656 if message is not None and not self.x_notify.hasFocus(): 656 if message is not None and not self.x_notify.has_focus():
657 if message is None: 657 if message is None:
658 message = _("{app}: a new event has just happened{entity}").format( 658 message = _("{app}: a new event has just happened{entity}").format(
659 app=C.APP_NAME, 659 app=C.APP_NAME,
660 entity=u' ({})'.format(entity) if entity else '') 660 entity=u' ({})'.format(entity) if entity else '')
661 self.x_notify.sendNotification(message) 661 self.x_notify.send_notification(message)
662 662
663 663
664 def newWidget(self, widget, user_action=False): 664 def new_widget(self, widget, user_action=False):
665 """Method called when a new widget is created 665 """Method called when a new widget is created
666 666
667 if suitable, the widget will be displayed 667 if suitable, the widget will be displayed
668 @param widget(widget.PrimitivusWidget): created widget 668 @param widget(widget.PrimitivusWidget): created widget
669 @param user_action(bool): if True, the widget has been created following an 669 @param user_action(bool): if True, the widget has been created following an
670 explicit user action. In this case, the widget may get focus immediately 670 explicit user action. In this case, the widget may get focus immediately
671 """ 671 """
672 # FIXME: when several widgets are possible (e.g. with :split) 672 # FIXME: when several widgets are possible (e.g. with :split)
673 # do not replace current widget when self.selected_widget != None 673 # do not replace current widget when self.selected_widget != None
674 if user_action or self.selected_widget is None: 674 if user_action or self.selected_widget is None:
675 self.selectWidget(widget) 675 self.select_widget(widget)
676 676
677 def selectWidget(self, widget): 677 def select_widget(self, widget):
678 """Display a widget if possible, 678 """Display a widget if possible,
679 679
680 else add it in the notification bar queue 680 else add it in the notification bar queue
681 @param widget: BoxWidget 681 @param widget: BoxWidget
682 """ 682 """
683 assert len(self.center_part.widget_list)<=2 683 assert len(self.center_part.widget_list)<=2
684 wid_idx = len(self.center_part.widget_list)-1 684 wid_idx = len(self.center_part.widget_list)-1
685 self.center_part.widget_list[wid_idx] = widget 685 self.center_part.widget_list[wid_idx] = widget
686 try: 686 try:
687 self.menu_roller.removeMenu(C.MENU_ID_WIDGET) 687 self.menu_roller.remove_menu(C.MENU_ID_WIDGET)
688 except KeyError: 688 except KeyError:
689 log.debug("No menu to delete") 689 log.debug("No menu to delete")
690 self.selected_widget = widget 690 self.selected_widget = widget
691 try: 691 try:
692 onSelected = self.selected_widget.onSelected 692 on_selected = self.selected_widget.on_selected
693 except AttributeError: 693 except AttributeError:
694 pass 694 pass
695 else: 695 else:
696 onSelected() 696 on_selected()
697 self._visible_widgets = set([widget]) # XXX: we can only have one widget visible at the time for now 697 self._visible_widgets = set([widget]) # XXX: we can only have one widget visible at the time for now
698 self.contact_lists.select(None) 698 self.contact_lists.select(None)
699 699
700 for wid in self.visible_widgets: # FIXME: check if widgets.getWidgets is not more appropriate 700 for wid in self.visible_widgets: # FIXME: check if widgets.get_widgets is not more appropriate
701 if isinstance(wid, Chat): 701 if isinstance(wid, Chat):
702 contact_list = self.contact_lists[wid.profile] 702 contact_list = self.contact_lists[wid.profile]
703 contact_list.select(wid.target) 703 contact_list.select(wid.target)
704 704
705 self.redraw() 705 self.redraw()
706 706
707 def removeWindow(self): 707 def remove_window(self):
708 """Remove window showed on the right column""" 708 """Remove window showed on the right column"""
709 #TODO: better Window management than this hack 709 #TODO: better Window management than this hack
710 assert len(self.center_part.widget_list) <= 2 710 assert len(self.center_part.widget_list) <= 2
711 wid_idx = len(self.center_part.widget_list)-1 711 wid_idx = len(self.center_part.widget_list)-1
712 self.center_part.widget_list[wid_idx] = urwid.Filler(urwid.Text('')) 712 self.center_part.widget_list[wid_idx] = urwid.Filler(urwid.Text(''))
713 self.center_part.focus_position = 0 713 self.center_part.focus_position = 0
714 self.redraw() 714 self.redraw()
715 715
716 def addProgress(self, pid, message, profile): 716 def add_progress(self, pid, message, profile):
717 """Follow a SàT progression 717 """Follow a SàT progression
718 718
719 @param pid: progression id 719 @param pid: progression id
720 @param message: message to show to identify the progression 720 @param message: message to show to identify the progression
721 """ 721 """
722 self.progress_wid.add(pid, message, profile) 722 self.progress_wid.add(pid, message, profile)
723 723
724 def setProgress(self, percentage): 724 def set_progress(self, percentage):
725 """Set the progression shown in notification bar""" 725 """Set the progression shown in notification bar"""
726 self.notif_bar.setProgress(percentage) 726 self.notif_bar.set_progress(percentage)
727 727
728 def contactSelected(self, contact_list, entity): 728 def contact_selected(self, contact_list, entity):
729 self.clearNotifs(entity, profile=contact_list.profile) 729 self.clear_notifs(entity, profile=contact_list.profile)
730 if entity.resource: 730 if entity.resource:
731 # we have clicked on a private MUC conversation 731 # we have clicked on a private MUC conversation
732 chat_widget = self.widgets.getOrCreateWidget(Chat, entity, on_new_widget=None, force_hash = Chat.getPrivateHash(contact_list.profile, entity), profile=contact_list.profile) 732 chat_widget = self.widgets.get_or_create_widget(Chat, entity, on_new_widget=None, force_hash = Chat.get_private_hash(contact_list.profile, entity), profile=contact_list.profile)
733 else: 733 else:
734 chat_widget = self.widgets.getOrCreateWidget(Chat, entity, on_new_widget=None, profile=contact_list.profile) 734 chat_widget = self.widgets.get_or_create_widget(Chat, entity, on_new_widget=None, profile=contact_list.profile)
735 self.selectWidget(chat_widget) 735 self.select_widget(chat_widget)
736 self.menu_roller.addMenu(_('Chat menu'), chat_widget.getMenu(), C.MENU_ID_WIDGET) 736 self.menu_roller.add_menu(_('Chat menu'), chat_widget.get_menu(), C.MENU_ID_WIDGET)
737 737
738 def _dialogOkCb(self, widget, data): 738 def _dialog_ok_cb(self, widget, data):
739 popup, answer_cb, answer_data = data 739 popup, answer_cb, answer_data = data
740 self.removePopUp(popup) 740 self.remove_pop_up(popup)
741 if answer_cb is not None: 741 if answer_cb is not None:
742 answer_cb(True, answer_data) 742 answer_cb(True, answer_data)
743 743
744 def _dialogCancelCb(self, widget, data): 744 def _dialog_cancel_cb(self, widget, data):
745 popup, answer_cb, answer_data = data 745 popup, answer_cb, answer_data = data
746 self.removePopUp(popup) 746 self.remove_pop_up(popup)
747 if answer_cb is not None: 747 if answer_cb is not None:
748 answer_cb(False, answer_data) 748 answer_cb(False, answer_data)
749 749
750 def showDialog(self, message, title="", type="info", answer_cb = None, answer_data = None): 750 def show_dialog(self, message, title="", type="info", answer_cb = None, answer_data = None):
751 if type == 'info': 751 if type == 'info':
752 popup = sat_widgets.Alert(title, message, ok_cb=answer_cb) 752 popup = sat_widgets.Alert(title, message, ok_cb=answer_cb)
753 if answer_cb is None: 753 if answer_cb is None:
754 popup.setCallback('ok', lambda dummy: self.removePopUp(popup)) 754 popup.set_callback('ok', lambda dummy: self.remove_pop_up(popup))
755 elif type == 'error': 755 elif type == 'error':
756 popup = sat_widgets.Alert(title, message, ok_cb=answer_cb) 756 popup = sat_widgets.Alert(title, message, ok_cb=answer_cb)
757 if answer_cb is None: 757 if answer_cb is None:
758 popup.setCallback('ok', lambda dummy: self.removePopUp(popup)) 758 popup.set_callback('ok', lambda dummy: self.remove_pop_up(popup))
759 elif type == 'yes/no': 759 elif type == 'yes/no':
760 popup = sat_widgets.ConfirmDialog(message) 760 popup = sat_widgets.ConfirmDialog(message)
761 popup.setCallback('yes', self._dialogOkCb, (popup, answer_cb, answer_data)) 761 popup.set_callback('yes', self._dialog_ok_cb, (popup, answer_cb, answer_data))
762 popup.setCallback('no', self._dialogCancelCb, (popup, answer_cb, answer_data)) 762 popup.set_callback('no', self._dialog_cancel_cb, (popup, answer_cb, answer_data))
763 else: 763 else:
764 popup = sat_widgets.Alert(title, message, ok_cb=answer_cb) 764 popup = sat_widgets.Alert(title, message, ok_cb=answer_cb)
765 if answer_cb is None: 765 if answer_cb is None:
766 popup.setCallback('ok', lambda dummy: self.removePopUp(popup)) 766 popup.set_callback('ok', lambda dummy: self.remove_pop_up(popup))
767 log.error(u'unmanaged dialog type: {}'.format(type)) 767 log.error(u'unmanaged dialog type: {}'.format(type))
768 self.showPopUp(popup) 768 self.show_pop_up(popup)
769 769
770 def dialogFailure(self, failure): 770 def dialog_failure(self, failure):
771 """Show a failure that has been returned by an asynchronous bridge method. 771 """Show a failure that has been returned by an asynchronous bridge method.
772 772
773 @param failure (defer.Failure): Failure instance 773 @param failure (defer.Failure): Failure instance
774 """ 774 """
775 self.alert(failure.classname, failure.message) 775 self.alert(failure.classname, failure.message)
776 776
777 def onNotification(self, notif_bar): 777 def on_notification(self, notif_bar):
778 """Called when a new notification has been received""" 778 """Called when a new notification has been received"""
779 if not isinstance(self.main_widget, PrimitivusTopWidget): 779 if not isinstance(self.main_widget, PrimitivusTopWidget):
780 #if we are not in the main configuration, we ignore the notifications bar 780 #if we are not in the main configuration, we ignore the notifications bar
781 return 781 return
782 if self.notif_bar.canHide(): 782 if self.notif_bar.can_hide():
783 #No notification left, we can hide the bar 783 #No notification left, we can hide the bar
784 self.main_widget.hide('notif_bar') 784 self.main_widget.hide('notif_bar')
785 else: 785 else:
786 self.main_widget.show('notif_bar') 786 self.main_widget.show('notif_bar')
787 self.redraw() # FIXME: invalidate cache in a more efficient way 787 self.redraw() # FIXME: invalidate cache in a more efficient way
788 788
789 def _actionManagerUnknownError(self): 789 def _action_manager_unknown_error(self):
790 self.alert(_("Error"), _(u"Unmanaged action")) 790 self.alert(_("Error"), _(u"Unmanaged action"))
791 791
792 def roomJoinedHandler(self, room_jid_s, room_nicks, user_nick, subject, profile): 792 def room_joined_handler(self, room_jid_s, room_nicks, user_nick, subject, profile):
793 super(PrimitivusApp, self).roomJoinedHandler(room_jid_s, room_nicks, user_nick, subject, profile) 793 super(PrimitivusApp, self).room_joined_handler(room_jid_s, room_nicks, user_nick, subject, profile)
794 # if self.selected_widget is None: 794 # if self.selected_widget is None:
795 # for contact_list in self.widgets.getWidgets(ContactList): 795 # for contact_list in self.widgets.get_widgets(ContactList):
796 # if profile in contact_list.profiles: 796 # if profile in contact_list.profiles:
797 # contact_list.setFocus(jid.JID(room_jid_s), True) 797 # contact_list.set_focus(jid.JID(room_jid_s), True)
798 798
799 def progressStartedHandler(self, pid, metadata, profile): 799 def progress_started_handler(self, pid, metadata, profile):
800 super(PrimitivusApp, self).progressStartedHandler(pid, metadata, profile) 800 super(PrimitivusApp, self).progress_started_handler(pid, metadata, profile)
801 self.addProgress(pid, metadata.get('name', _(u'unkown')), profile) 801 self.add_progress(pid, metadata.get('name', _(u'unkown')), profile)
802 802
803 def progressFinishedHandler(self, pid, metadata, profile): 803 def progress_finished_handler(self, pid, metadata, profile):
804 log.info(u"Progress {} finished".format(pid)) 804 log.info(u"Progress {} finished".format(pid))
805 super(PrimitivusApp, self).progressFinishedHandler(pid, metadata, profile) 805 super(PrimitivusApp, self).progress_finished_handler(pid, metadata, profile)
806 806
807 def progressErrorHandler(self, pid, err_msg, profile): 807 def progress_error_handler(self, pid, err_msg, profile):
808 log.warning(u"Progress {pid} error: {err_msg}".format(pid=pid, err_msg=err_msg)) 808 log.warning(u"Progress {pid} error: {err_msg}".format(pid=pid, err_msg=err_msg))
809 super(PrimitivusApp, self).progressErrorHandler(pid, err_msg, profile) 809 super(PrimitivusApp, self).progress_error_handler(pid, err_msg, profile)
810 810
811 811
812 ##DIALOGS CALLBACKS## 812 ##DIALOGS CALLBACKS##
813 def onJoinRoom(self, button, edit): 813 def on_join_room(self, button, edit):
814 self.removePopUp() 814 self.remove_pop_up()
815 room_jid = jid.JID(edit.get_edit_text()) 815 room_jid = jid.JID(edit.get_edit_text())
816 self.bridge.mucJoin(room_jid, self.profiles[self.current_profile].whoami.node, {}, self.current_profile, callback=lambda dummy: None, errback=self.dialogFailure) 816 self.bridge.muc_join(room_jid, self.profiles[self.current_profile].whoami.node, {}, self.current_profile, callback=lambda dummy: None, errback=self.dialog_failure)
817 817
818 #MENU EVENTS# 818 #MENU EVENTS#
819 def onConnectRequest(self, menu): 819 def on_connect_request(self, menu):
820 QuickApp.connect(self, self.current_profile) 820 QuickApp.connect(self, self.current_profile)
821 821
822 def onDisconnectRequest(self, menu): 822 def on_disconnect_request(self, menu):
823 self.disconnect(self.current_profile) 823 self.disconnect(self.current_profile)
824 824
825 def onParam(self, menu): 825 def on_param(self, menu):
826 def success(params): 826 def success(params):
827 ui = xmlui.create(self, xml_data=params, profile=self.current_profile) 827 ui = xmlui.create(self, xml_data=params, profile=self.current_profile)
828 ui.show() 828 ui.show()
829 829
830 def failure(error): 830 def failure(error):
831 self.alert(_("Error"), _("Can't get parameters (%s)") % error) 831 self.alert(_("Error"), _("Can't get parameters (%s)") % error)
832 self.bridge.getParamsUI(app=C.APP_NAME, profile_key=self.current_profile, callback=success, errback=failure) 832 self.bridge.param_ui_get(app=C.APP_NAME, profile_key=self.current_profile, callback=success, errback=failure)
833 833
834 def onExitRequest(self, menu): 834 def on_exit_request(self, menu):
835 QuickApp.onExit(self) 835 QuickApp.on_exit(self)
836 try: 836 try:
837 if self._bracketed_mode_set: # we don't unset if bracketed paste mode was detected automatically (i.e. not in conf) 837 if self._bracketed_mode_set: # we don't unset if bracketed paste mode was detected automatically (i.e. not in conf)
838 log.debug("unsetting bracketed paste mode") 838 log.debug("unsetting bracketed paste mode")
839 sys.stdout.write("\033[?2004l") 839 sys.stdout.write("\033[?2004l")
840 except AttributeError: 840 except AttributeError:
841 pass 841 pass
842 raise urwid.ExitMainLoop() 842 raise urwid.ExitMainLoop()
843 843
844 def onJoinRoomRequest(self, menu): 844 def on_join_room_request(self, menu):
845 """User wants to join a MUC room""" 845 """User wants to join a MUC room"""
846 pop_up_widget = sat_widgets.InputDialog(_("Entering a MUC room"), _("Please enter MUC's JID"), default_txt=self.bridge.mucGetDefaultService(), ok_cb=self.onJoinRoom) 846 pop_up_widget = sat_widgets.InputDialog(_("Entering a MUC room"), _("Please enter MUC's JID"), default_txt=self.bridge.muc_get_default_service(), ok_cb=self.on_join_room)
847 pop_up_widget.setCallback('cancel', lambda dummy: self.removePopUp(pop_up_widget)) 847 pop_up_widget.set_callback('cancel', lambda dummy: self.remove_pop_up(pop_up_widget))
848 self.showPopUp(pop_up_widget) 848 self.show_pop_up(pop_up_widget)
849 849
850 def onAboutRequest(self, menu): 850 def on_about_request(self, menu):
851 self.alert(_("About"), C.APP_NAME + " v" + self.bridge.getVersion()) 851 self.alert(_("About"), C.APP_NAME + " v" + self.bridge.version_get())
852 852
853 #MISC CALLBACKS# 853 #MISC CALLBACKS#
854 854
855 def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): 855 def set_presence_status(self, show='', status=None, profile=C.PROF_KEY_NONE):
856 contact_list_wid = self.widgets.getWidget(ContactList, profiles=profile) 856 contact_list_wid = self.widgets.get_widget(ContactList, profiles=profile)
857 if contact_list_wid is not None: 857 if contact_list_wid is not None:
858 contact_list_wid.status_bar.setPresenceStatus(show, status) 858 contact_list_wid.status_bar.set_presence_status(show, status)
859 else: 859 else:
860 log.warning(u"No ContactList widget found for profile {}".format(profile)) 860 log.warning(u"No ContactList widget found for profile {}".format(profile))
861 861
862 if __name__ == '__main__': 862 if __name__ == '__main__':
863 PrimitivusApp().start() 863 PrimitivusApp().start()