diff frontends/src/primitivus/primitivus @ 1265:e3a9ea76de35 frontends_multi_profiles

quick_frontend, primitivus: multi-profiles refactoring part 1 (big commit, sorry :p): This refactoring allow primitivus to manage correctly several profiles at once, with various other improvments: - profile_manager can now plug several profiles at once, requesting password when needed. No more profile plug specific method is used anymore in backend, instead a "validated" key is used in actions - Primitivus widget are now based on a common "PrimitivusWidget" classe which mainly manage the decoration so far - all widgets are treated in the same way (contactList, Chat, Progress, etc), no more chat_wins specific behaviour - widgets are created in a dedicated manager, with facilities to react on new widget creation or other events - quick_frontend introduce a new QuickWidget class, which aims to be as generic and flexible as possible. It can manage several targets (jids or something else), and several profiles - each widget class return a Hash according to its target. For example if given a target jid and a profile, a widget class return a hash like (target.bare, profile), the same widget will be used for all resources of the same jid - better management of CHAT_GROUP mode for Chat widgets - some code moved from Primitivus to QuickFrontend, the final goal is to have most non backend code in QuickFrontend, and just graphic code in subclasses - no more (un)escapePrivate/PRIVATE_PREFIX - contactList improved a lot: entities not in roster and special entities (private MUC conversations) are better managed - resources can be displayed in Primitivus, and their status messages - profiles are managed in QuickFrontend with dedicated managers This is work in progress, other frontends are broken. Urwid SàText need to be updated. Most of features of Primitivus should work as before (or in a better way ;))
author Goffi <goffi@goffi.org>
date Wed, 10 Dec 2014 19:00:09 +0100
parents 82dabb442e2e
children faa1129559b8
line wrap: on
line diff
--- a/frontends/src/primitivus/primitivus	Wed Dec 10 18:37:14 2014 +0100
+++ b/frontends/src/primitivus/primitivus	Wed Dec 10 19:00:09 2014 +0100
@@ -28,8 +28,8 @@
 from urwid_satext import sat_widgets
 from urwid_satext.files_management import FileDialog
 from sat_frontends.quick_frontend.quick_app import QuickApp
-from sat_frontends.quick_frontend.quick_chat_list import QuickChatList
-from sat_frontends.quick_frontend.quick_utils import getNewPath, unescapePrivate
+from sat_frontends.quick_frontend.quick_utils import getNewPath
+from sat_frontends.quick_frontend import quick_chat
 from sat_frontends.primitivus.profile_manager import ProfileManager
 from sat_frontends.primitivus.contact_list import ContactList
 from sat_frontends.primitivus.chat import Chat
@@ -39,35 +39,28 @@
 from sat_frontends.primitivus.keys import action_key_map as a_key
 from sat_frontends.primitivus import config
 from sat_frontends.tools.misc import InputHistory
-from sat_frontends.constants import Const as commonConst # FIXME
-from sat_frontends.tools.jid import JID
+from sat_frontends.tools import jid
 from os.path import join
 import signal
 
 
-class ChatList(QuickChatList):
-    """This class manage the list of chat windows"""
-
-    def createChat(self, target):
-        return Chat(target, self.host)
-
 
 class EditBar(sat_widgets.ModalEdit):
     """
     The modal edit bar where you would enter messages and commands.
     """
 
-    def __init__(self, app):
-        modes = {None: ('NORMAL', u''),
-                 a_key['MODE_INSERTION']: ('INSERTION', u'> '),
-                 a_key['MODE_COMMAND']: ('COMMAND', u':')} #XXX: captions *MUST* be unicode
+    def __init__(self, host):
+        modes = {None: (C.MODE_NORMAL, u''),
+                 a_key['MODE_INSERTION']: (C.MODE_INSERTION, u'> '),
+                 a_key['MODE_COMMAND']: (C.MODE_COMMAND, u':')} #XXX: captions *MUST* be unicode
         super(EditBar, self).__init__(modes)
-        self.app = app
+        self.host = host
         self.setCompletionMethod(self._text_completion)
         urwid.connect_signal(self, 'click', self.onTextEntered)
 
     def _text_completion(self, text, completion_data, mode):
-        if mode == 'INSERTION':
+        if mode == C.MODE_INSERTION:
             return self._nick_completion(text, completion_data)
         else:
             return text
@@ -75,9 +68,9 @@
     def _nick_completion(self, text, completion_data):
         """Completion method which complete pseudo in group chat
         for params, see AdvancedEdit"""
-        contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once
+        contact = self.host.contact_list.getContact() ###Based on the fact that there is currently only one contact selectable at once
         if contact:
-            chat = self.app.chat_wins[contact]
+            chat = self.host.chat_wins[contact]
             if chat.type != "group":
                 return text
             space = text.rfind(" ")
@@ -98,18 +91,17 @@
 
     def onTextEntered(self, editBar):
         """Called when text is entered in the main edit bar"""
-        if self.mode == 'INSERTION':
-            contact = self.app.contact_list.getContact() ###Based on the fact that there is currently only one contact selectableat once
-            if contact:
-                chat = self.app.chat_wins[contact]
-                self.app.sendMessage(contact,
+        if self.mode == C.MODE_INSERTION:
+            if isinstance(self.host.selected_widget, quick_chat.QuickChat):
+                chat_widget = self.host.selected_widget
+                self.host.sendMessage(chat_widget.target,
                                      editBar.get_edit_text(),
-                                     mess_type = "groupchat" if chat.type == 'group' else "chat",
-                                     errback=lambda failure: self.app.notify(_("Error while sending message (%s)") % failure),
-                                     profile_key=self.app.profile
+                                     mess_type = "groupchat" if chat_widget.type == 'group' else "chat", # TODO: put this in QuickChat
+                                     errback=lambda failure: self.host.notify(_("Error while sending message ({})").format(failure)),
+                                     profile_key=chat_widget.profile
                                     )
                 editBar.set_edit_text('')
-        elif self.mode == 'COMMAND':
+        elif self.mode == C.MODE_COMMAND:
             self.commandHandler()
 
     def commandHandler(self):
@@ -118,42 +110,44 @@
         tokens = self.get_edit_text().split(' ')
         command, args = tokens[0], tokens[1:]
         if command == 'quit':
-            self.app.onExit()
+            self.host.onExit()
             raise urwid.ExitMainLoop()
         elif command == 'messages':
             wid = sat_widgets.GenericList(logging.memoryGet())
-            self.app.addWindow(wid)
-        elif command == 'presence':
-            values = [value for value in commonConst.PRESENCE.keys()]
-            values = [value if value else 'online' for value in values]  # the empty value actually means 'online'
-            if args and args[0] in values:
-                presence = '' if args[0] == 'online' else args[0]
-                self.app.status_bar.onChange(user_data=sat_widgets.ClickableText(commonConst.PRESENCE[presence]))
-            else:
-                self.app.status_bar.onPresenceClick()
-        elif command == 'status':
-            if args:
-                self.app.status_bar.onChange(user_data=sat_widgets.AdvancedEdit(args[0]))
-            else:
-                self.app.status_bar.onStatusClick()
+            self.host.selectWidget(wid)
+        # elif command == 'presence':
+        #     values = [value for value in commonConst.PRESENCE.keys()]
+        #     values = [value if value else 'online' for value in values]  # the empty value actually means 'online'
+        #     if args and args[0] in values:
+        #         presence = '' if args[0] == 'online' else args[0]
+        #         self.host.status_bar.onChange(user_data=sat_widgets.ClickableText(commonConst.PRESENCE[presence]))
+        #     else:
+        #         self.host.status_bar.onPresenceClick()
+        # elif command == 'status':
+        #     if args:
+        #         self.host.status_bar.onChange(user_data=sat_widgets.AdvancedEdit(args[0]))
+        #     else:
+        #         self.host.status_bar.onStatusClick()
         elif command == 'history':
-            try:
-                limit = int(args[0])
-            except (IndexError, ValueError):
-                limit = 50
-            win = self.app.chat_wins[JID(self.app.contact_list.selected).bare]
-            win.clearHistory()
-            if limit > 0:
-                win.historyPrint(size=limit, profile=self.app.profile)
+            widget = self.host.selected_widget
+            if isinstance(widget, quick_chat.QuickChat):
+                try:
+                    limit = int(args[0])
+                except (IndexError, ValueError):
+                    limit = 50
+                widget.clearHistory()
+                if limit > 0:
+                    widget.historyPrint(size=limit, profile=widget.profile)
         elif command == 'search':
-            pattern = " ".join(args)
-            if not pattern:
-                self.app.notif_bar.addMessage(D_("Please specify the globbing pattern to search for"))
-            win = self.app.chat_wins[JID(self.app.contact_list.selected).bare]
-            win.clearHistory()
-            win.printInfo(D_("Results for searching the globbing pattern: %s") % pattern, timestamp=0)
-            win.historyPrint(size=C.HISTORY_LIMIT_NONE, search=pattern, profile=self.app.profile)
-            win.printInfo(D_("Type ':history <lines>' to reset the chat history"))
+            widget = self.host.selected_widget
+            if isinstance(widget, quick_chat.QuickChat):
+                pattern = " ".join(args)
+                if not pattern:
+                    self.host.notif_bar.addMessage(D_("Please specify the globbing pattern to search for"))
+                widget.clearHistory()
+                widget.printInfo(D_("Results for searching the globbing pattern: %s") % pattern, timestamp=0)
+                widget.historyPrint(size=C.HISTORY_LIMIT_NONE, search=pattern, profile=widget.profile)
+                widget.printInfo(D_("Type ':history <lines>' to reset the chat history"))
         else:
             return
         self.set_edit_text('')
@@ -167,22 +161,24 @@
         and move the index of the temporary history stack."""
         if key == a_key['MODAL_ESCAPE']:
             # first save the text to the current mode, then change to NORMAL
-            self.app._updateInputHistory(self.get_edit_text(), mode=self.mode)
-            self.app._updateInputHistory(mode='NORMAL')
-        if self._mode == 'NORMAL' and key in self._modes:
-            self.app._updateInputHistory(mode=self._modes[key][0])
+            self.host._updateInputHistory(self.get_edit_text(), mode=self.mode)
+            self.host._updateInputHistory(mode=C.MODE_NORMAL)
+        if self._mode == C.MODE_NORMAL and key in self._modes:
+            self.host._updateInputHistory(mode=self._modes[key][0])
         if key == a_key['HISTORY_PREV']:
-            self.app._updateInputHistory(self.get_edit_text(), -1, self._historyCb, self.mode)
+            self.host._updateInputHistory(self.get_edit_text(), -1, self._historyCb, self.mode)
             return
         elif key == a_key['HISTORY_NEXT']:
-            self.app._updateInputHistory(self.get_edit_text(), +1, self._historyCb, self.mode)
+            self.host._updateInputHistory(self.get_edit_text(), +1, self._historyCb, self.mode)
             return
         elif key == a_key['EDIT_ENTER']:
-            self.app._updateInputHistory(self.get_edit_text(), mode=self.mode)
+            self.host._updateInputHistory(self.get_edit_text(), mode=self.mode)
         else:
-            contact = self.app.contact_list.getContact()
-            if contact:
-                self.app.bridge.chatStateComposing(unescapePrivate(contact), self.app.profile)
+            if (self._mode == C.MODE_INSERTION
+                and isinstance(self.host.selected_widget, quick_chat.QuickChat)
+                and key not in sat_widgets.FOCUS_KEYS):
+                self.host.bridge.chatStateComposing(self.host.selected_widget.target, self.host.selected_widget.profile)
+
         return super(EditBar, self).keypress(size, key)
 
 
@@ -287,12 +283,13 @@
         self.main_widget = ProfileManager(self)
         self.loop = urwid.MainLoop(self.main_widget, C.PALETTE, event_loop=urwid.GLibEventLoop(), input_filter=self.inputFilter, unhandled_input=self.keyHandler)
 
+
         ##misc setup##
-        self.chat_wins = ChatList(self)
         self.notif_bar = sat_widgets.NotificationBar()
         urwid.connect_signal(self.notif_bar, 'change', self.onNotification)
-        self.progress_wid = Progress(self)
-        urwid.connect_signal(self.notif_bar.progress, 'click', lambda x: self.addWindow(self.progress_wid))
+
+        self.progress_wid = self.widgets.getOrCreateWidget(Progress, None, on_new_widget=None)
+        urwid.connect_signal(self.notif_bar.progress, 'click', lambda x: self.selectWidget(self.progress_wid))
         self.__saved_overlay = None
 
         self.x_notify = Notify()
@@ -351,7 +348,7 @@
                 self._early_popup = popup
             else:
                 self.showPopUp(popup)
-        super(PrimitivusApp, self).postInit()
+        super(PrimitivusApp, self).postInit(self.main_widget)
 
     def inputFilter(self, input_, raw):
         if self.__saved_overlay and input_ != a_key['OVERLAY_HIDE']:
@@ -387,14 +384,14 @@
 
         elif input_ == a_key['DEBUG'] and 'D' in self.bridge.getVersion(): #Debug only for dev versions
             self.debug()
-        elif input_ == a_key['CONTACTS_HIDE']: #user wants to (un)hide the contact_list
+        elif input_ == a_key['CONTACTS_HIDE']: #user wants to (un)hide the contact lists
             try:
                 for wid, options in self.center_part.contents:
-                    if self.contact_list is wid:
+                    if self.contact_lists_pile is wid:
                         self.center_part.contents.remove((wid, options))
                         break
                 else:
-                    self.center_part.contents.insert(0, (self.contact_list, ('weight', 2, False)))
+                    self.center_part.contents.insert(0, (self.contact_lists_pile, ('weight', 2, False)))
             except AttributeError:
                 #The main widget is not built (probably in Profile Manager)
                 pass
@@ -413,17 +410,18 @@
         except AttributeError:
             return input_
 
-    def addMenus(self, menu, type_, menu_data=None):
+    def addMenus(self, menu, type_filter, menu_data=None):
         """Add cached menus to instance
         @param menu: sat_widgets.Menu instance
-        @param type_: menu type like is sat.core.sat_main.importMenu
+        @param type_filter: menu type like is sat.core.sat_main.importMenu
         @param menu_data: data to send with these menus
 
         """
-        menus = self.profiles[self.profile]['menus'].get(type_,[])
         def add_menu_cb(callback_id):
-            self.launchAction(callback_id, menu_data, profile_key = self.profile)
-        for id_, path, path_i18n  in menus:
+            self.launchAction(callback_id, menu_data, profile=self.current_profile)
+        for id_, type_, path, path_i18n  in self.bridge.getMenus("", C.NO_SECURITY_LIMIT ):
+            if type_ != type_filter:
+                continue
             if len(path) != 2:
                 raise NotImplementedError("Menu with a path != 2 are not implemented yet")
             menu.addMenu(path_i18n[0], path_i18n[1], lambda dummy,id_=id_: add_menu_cb(id_))
@@ -445,23 +443,28 @@
         #FIXME: do this in a more generic way (in quickapp)
         self.addMenus(menu, C.MENU_GLOBAL)
 
-        menu_roller = sat_widgets.MenuRoller([(_('Main menu'),menu)])
+        menu_roller = sat_widgets.MenuRoller([(_('Main menu'), menu, C.MENU_ID_MAIN)])
         return menu_roller
 
     def _buildMainWidget(self):
-        self.contact_list = ContactList(self, on_click=self.contactSelected, on_change=lambda w: self.redraw())
-        #self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))])
-        self.center_part = urwid.Columns([('weight', 2, self.contact_list), ('weight', 8, urwid.Filler(urwid.Text('')))])
+        self.contact_lists_pile = urwid.Pile([])
+        #self.center_part = urwid.Columns([('weight',2,self.contact_lists[profile]),('weight',8,Chat('',self))])
+        self.center_part = urwid.Columns([('weight', 2, self.contact_lists_pile), ('weight', 8, urwid.Filler(urwid.Text('')))])
 
         self.editBar = EditBar(self)
         self.menu_roller = self._buildMenuRoller()
         self.main_widget = PrimitivusTopWidget(self.center_part, self.menu_roller, self.notif_bar, self.editBar)
         return self.main_widget
 
-    def plug_profile_1(self, profile_key='@DEFAULT@'):
+    def addContactList(self, profile):
+        contact_list = ContactList(self, on_click=self.contactSelected, on_change=lambda w: self.redraw(), profile=profile)
+        self.contact_lists_pile.contents.append((contact_list, ('weight', 1)))
+        self.contact_lists[profile] = contact_list
+        return contact_list
+
+    def plugging_profiles(self):
         self.loop.widget = self._buildMainWidget()
         self.redraw()
-        QuickApp.plug_profile_1(self, profile_key)
         try:
             # if a popup arrived before main widget is build, we need to show it now
             self.showPopUp(self._early_popup)
@@ -492,15 +495,32 @@
         self.notif_bar.addMessage(message)
         self.redraw()
 
-    def addWindow(self, widget):
-        """Display a window if possible,
+    def newWidget(self, widget):
+        """Display a widget if possible,
+
         else add it in the notification bar queue
-        @param widget: BoxWidget"""
-        assert(len(self.center_part.widget_list)<=2)
+        @param widget: BoxWidget
+        """
+        self.selectWidget(widget)
+
+    def selectWidget(self, widget):
+        assert len(self.center_part.widget_list)<=2
         wid_idx = len(self.center_part.widget_list)-1
         self.center_part.widget_list[wid_idx] = widget
-        self.menu_roller.removeMenu(_('Chat menu'))
-        self.contact_list.unselectAll()
+        try:
+            self.menu_roller.removeMenu(C.MENU_ID_WIDGET)
+        except KeyError:
+            log.debug("No menu to delete")
+        self.selected_widget = widget
+        self.visible_widgets = set([widget]) # XXX: we can only have one widget visible at the time for now
+        for contact_list in self.contact_lists.itervalues():
+            contact_list.unselectAll()
+
+        for wid in self.visible_widgets:
+            if isinstance(wid, Chat):
+                contact_list = self.contact_lists[wid.profile]
+                contact_list.select(wid.target)
+
         self.redraw()
 
     def removeWindow(self):
@@ -522,23 +542,29 @@
         """Set the progression shown in notification bar"""
         self.notif_bar.setProgress(percentage)
 
-    def contactSelected(self, contact_list):
-        contact = contact_list.getContact()
-        if contact:
-            assert(len(self.center_part.widget_list)==2)
-            self.center_part.widget_list[1] = self.chat_wins[contact]
-            self.menu_roller.addMenu(_('Chat menu'), self.chat_wins[contact].getMenu())
+    def contactSelected(self, contact_list, entity):
+        if entity.resource:
+            # we have clicked on a private MUC conversation
+            chat_widget = self.widgets.getOrCreateWidget(Chat, entity, on_new_widget=None, force_hash = Chat.getPrivateHash(contact_list.profile, entity), profile=contact_list.profile)
+        else:
+            chat_widget = self.widgets.getOrCreateWidget(Chat, entity, on_new_widget=None, profile=contact_list.profile)
+        self.selectWidget(chat_widget)
+        self.menu_roller.addMenu(_('Chat menu'), chat_widget.getMenu(), C.MENU_ID_WIDGET)
 
-    def newMessageHandler(self, from_jid, to_jid, msg, _type, extra, profile):
-        QuickApp.newMessageHandler(self, from_jid, to_jid, msg, _type, extra, profile)
+    def newMessageHandler(self, from_jid, to_jid, msg, type_, extra, profile):
+        QuickApp.newMessageHandler(self, from_jid, to_jid, msg, type_, extra, profile)
 
-        if not from_jid in self.contact_list and from_jid.bare != self.profiles[profile]['whoami'].bare:
+        if not from_jid in self.contact_lists[profile] and from_jid.bare != self.profiles[profile].whoami.bare:
             #XXX: needed to show entities which haven't sent any
             #     presence information and which are not in roster
-            self.contact_list.replace(from_jid, [C.GROUP_NOT_IN_ROSTER])
-
-        if self.contact_list.selected is None or JID(self.contact_list.selected).bare != from_jid.bare:
-            self.contact_list.putAlert(from_jid)
+            self.contact_lists[profile].setContact(from_jid)
+        visible = False
+        for widget in self.visible_widgets:
+            if isinstance(widget, Chat) and widget.manageMessage(from_jid, type_):
+                visible = True
+                break
+        if not visible:
+            self.contact_lists[profile].setAlert(from_jid.bare if type_ == C.MESS_TYPE_GROUPCHAT else from_jid)
 
     def _dialogOkCb(self, widget, data):
         self.removePopUp()
@@ -552,7 +578,6 @@
         answer_data = [data[1]] if data[1] else []
         answer_cb(False, *answer_data)
 
-
     def showDialog(self, message, title="", type_="info", answer_cb = None, answer_data = None):
         if type_ == 'info':
             popup = sat_widgets.Alert(unicode(title), unicode(message), ok_cb=answer_cb or self.removePopUp) #FIXME: remove unicode here when DBus Bridge will no return dbus.String anymore
@@ -578,11 +603,15 @@
         else:
             self.main_widget.show('notif_bar')
 
-    def launchAction(self, callback_id, data=None, profile_key="@NONE@"):
+    def launchAction(self, callback_id, data=None, callback=None, profile=C.PROF_KEY_NONE):
         """ Launch a dynamic action
         @param callback_id: id of the action to launch
         @param data: data needed only for certain actions
-        @param profile_key: %(doc_profile_key)s
+        @param callback: if not None and 'validated' key is present, it will be called with the following parameters:
+            - callback_id
+            - data
+            - profile
+        @param profile: %(doc_profile)s
 
         """
         if data is None:
@@ -593,24 +622,20 @@
                 # action was a one shot, nothing to do
                 pass
             elif "xmlui" in data:
-                ui = xmlui.create(self, xml_data=data['xmlui'])
+                ui = xmlui.create(self, xml_data=data['xmlui'], callback=callback, profile=profile)
                 ui.show()
-            elif "authenticated_profile" in data:
-                assert("caller" in data)
-                if data["caller"] == "profile_manager":
-                    assert(isinstance(self.main_widget, ProfileManager))
-                    self.main_widget.getXMPPParams(data['authenticated_profile'])
-                elif data["caller"] == "plug_profile":
-                    self.plug_profile_1(data['authenticated_profile'])
-                else:
-                    raise NotImplementedError
+            elif 'validated' in data:
+                pass # this key is managed below
             else:
                 self.showPopUp(sat_widgets.Alert(_("Error"), _(u"Unmanaged action result"), ok_cb=self.removePopUp))
 
+            if callback and 'validated' in data:
+                callback(callback_id, data, profile)
+
         def action_eb(failure):
             self.showPopUp(sat_widgets.Alert(failure.fullname, failure.message, ok_cb=self.removePopUp))
 
-        self.bridge.launchAction(callback_id, data, profile_key, callback=action_cb, errback=action_eb)
+        self.bridge.launchAction(callback_id, data, profile, callback=action_cb, errback=action_eb)
 
     def askConfirmationHandler(self, confirmation_id, confirmation_type, data, profile):
         answer_data={}
@@ -684,23 +709,30 @@
             log.error (_("FIXME FIXME FIXME: type [%s] not implemented") % type_)
             raise NotImplementedError
 
+
+    def roomJoinedHandler(self, room_jid_s, room_nicks, user_nick, profile):
+        super(PrimitivusApp, self).roomJoinedHandler(room_jid_s, room_nicks, user_nick, profile)
+        self.contact_lists[profile].setFocus(jid.JID(room_jid_s), True)
+
+
+
     ##DIALOGS CALLBACKS##
     def onJoinRoom(self, button, edit):
         self.removePopUp()
-        room_jid = JID(edit.get_edit_text())
+        room_jid = jid.JID(edit.get_edit_text())
         if room_jid.is_valid():
-            self.bridge.joinMUC(room_jid, self.profiles[self.profile]['whoami'].node, {}, self.profile)
+            self.bridge.joinMUC(room_jid, self.profiles[self.current_profile].whoami.node, {}, self.current_profile)
         else:
-            message = _("'%s' is an invalid JID !") % room_jid
+            message = _("'%s' is an invalid jid.JID !") % room_jid
             log.error (message)
             self.showPopUp(sat_widgets.Alert(_("Error"), message, ok_cb=self.removePopUp))
 
     #MENU EVENTS#
     def onConnectRequest(self, menu):
-        QuickApp.asyncConnect(self, self.profile)
+        QuickApp.asyncConnect(self, self.current_profile)
 
     def onDisconnectRequest(self, menu):
-        self.bridge.disconnect(self.profile)
+        self.bridge.disconnect(self.current_profile)
 
     def onParam(self, menu):
         def success(params):
@@ -709,7 +741,7 @@
 
         def failure(error):
             self.showPopUp(sat_widgets.Alert(_("Error"), _("Can't get parameters (%s)") % error, ok_cb=self.removePopUp))
-        self.bridge.getParamsUI(app=C.APP_NAME, profile_key=self.profile, callback=success, errback=failure)
+        self.bridge.getParamsUI(app=C.APP_NAME, profile_key=self.current_profile, callback=success, errback=failure)
 
     def onExitRequest(self, menu):
         QuickApp.onExit(self)
@@ -725,12 +757,12 @@
 
     #MISC CALLBACKS#
 
-    def setStatusOnline(self, online=True, show="", statuses={}):
+    def setStatusOnline(self, online=True, show="", statuses={}, profile=C.PROF_KEY_NONE):
         if not online or not statuses:
-            self.status_bar.setPresenceStatus(show if online else 'unavailable', '')
+            self.contact_lists[profile].status_bar.setPresenceStatus(show if online else 'unavailable', '')
             return
         try:
-            self.status_bar.setPresenceStatus(show, statuses['default'])
+            self.contact_lists[profile].status_bar.setPresenceStatus(show, statuses['default'])
         except (KeyError, TypeError):
             pass