Mercurial > libervia-backend
diff libervia/tui/profile_manager.py @ 4076:b620a8e882e1
refactoring: rename `libervia.frontends.primitivus` to `libervia.tui`
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 02 Jun 2023 16:25:25 +0200 |
parents | libervia/frontends/primitivus/profile_manager.py@26b7ed2817da |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/tui/profile_manager.py Fri Jun 02 16:25:25 2023 +0200 @@ -0,0 +1,228 @@ +#!/usr/bin/env python3 + + +# Libervia TUI +# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from libervia.backend.core.i18n import _ +from libervia.backend.core import log as logging + +log = logging.getLogger(__name__) +from libervia.frontends.quick_frontend.quick_profile_manager import QuickProfileManager +from libervia.tui.constants import Const as C +from libervia.tui.keys import action_key_map as a_key +from urwid_satext import sat_widgets +import urwid + + +class ProfileManager(QuickProfileManager, urwid.WidgetWrap): + def __init__(self, host, autoconnect=None): + QuickProfileManager.__init__(self, host, autoconnect) + + # login & password box must be created before list because of on_profile_change + self.login_wid = sat_widgets.AdvancedEdit(_("Login:"), align="center") + self.pass_wid = sat_widgets.Password(_("Password:"), align="center") + + style = ["no_first_select"] + profiles = host.bridge.profiles_list_get() + profiles.sort() + self.list_profile = sat_widgets.List( + profiles, style=style, align="center", on_change=self.on_profile_change + ) + + # new & delete buttons + buttons = [ + urwid.Button(_("New"), self.on_new_profile), + urwid.Button(_("Delete"), self.on_delete_profile), + ] + buttons_flow = urwid.GridFlow( + buttons, + max([len(button.get_label()) for button in buttons]) + 4, + 1, + 1, + "center", + ) + + # second part: login information: + divider = urwid.Divider("-") + + # connect button + connect_button = sat_widgets.CustomButton( + _("Connect"), self.on_connect_profiles, align="center" + ) + + # we now build the widget + list_walker = urwid.SimpleFocusListWalker( + [ + buttons_flow, + self.list_profile, + divider, + self.login_wid, + self.pass_wid, + connect_button, + ] + ) + frame_body = urwid.ListBox(list_walker) + frame = urwid.Frame( + frame_body, + urwid.AttrMap(urwid.Text(_("Profile Manager"), align="center"), "title"), + ) + self.main_widget = urwid.LineBox(frame) + urwid.WidgetWrap.__init__(self, self.main_widget) + + self.go(autoconnect) + + def keypress(self, size, key): + if key == a_key["APP_QUIT"]: + self.host.on_exit() + raise urwid.ExitMainLoop() + elif key in (a_key["FOCUS_UP"], a_key["FOCUS_DOWN"]): + focus_diff = 1 if key == a_key["FOCUS_DOWN"] else -1 + list_box = self.main_widget.base_widget.body + current_focus = list_box.body.get_focus()[1] + if current_focus is None: + return + while True: + current_focus += focus_diff + if current_focus < 0 or current_focus >= len(list_box.body): + break + if list_box.body[current_focus].selectable(): + list_box.set_focus( + current_focus, "above" if focus_diff == 1 else "below" + ) + list_box._invalidate() + return + return super(ProfileManager, self).keypress(size, key) + + def cancel_dialog(self, button): + self.host.remove_pop_up() + + def new_profile(self, button, edit): + """Create the profile""" + name = edit.get_edit_text() + self.host.bridge.profile_create( + name, + callback=lambda: self.new_profile_created(name), + errback=self.profile_creation_failure, + ) + + def new_profile_created(self, profile): + # new profile will be selected, and a selected profile assume the session is started + self.host.bridge.profile_start_session( + "", + profile, + callback=lambda __: self.new_profile_session_started(profile), + errback=self.profile_creation_failure, + ) + + def new_profile_session_started(self, profile): + self.host.remove_pop_up() + self.refill_profiles() + self.list_profile.select_value(profile) + self.current.profile = profile + self.get_connection_params(profile) + self.host.redraw() + + def profile_creation_failure(self, reason): + self.host.remove_pop_up() + message = self._get_error_message(reason) + self.host.alert(_("Can't create profile"), message) + + def delete_profile(self, button): + self._delete_profile() + self.host.remove_pop_up() + + def on_new_profile(self, e): + pop_up_widget = sat_widgets.InputDialog( + _("New profile"), + _("Please enter a new profile name"), + cancel_cb=self.cancel_dialog, + ok_cb=self.new_profile, + ) + self.host.show_pop_up(pop_up_widget) + + def on_delete_profile(self, e): + if self.current.profile: + pop_up_widget = sat_widgets.ConfirmDialog( + _("Are you sure you want to delete the profile {} ?").format( + self.current.profile + ), + no_cb=self.cancel_dialog, + yes_cb=self.delete_profile, + ) + self.host.show_pop_up(pop_up_widget) + + def on_connect_profiles(self, button): + """Connect the profiles and start the main widget + + @param button: the connect button + """ + self._on_connect_profiles() + + def reset_fields(self): + """Set profile to None, and reset fields""" + super(ProfileManager, self).reset_fields() + self.list_profile.unselect_all(invisible=True) + + def set_profiles(self, profiles): + """Update the list of profiles""" + self.list_profile.change_values(profiles) + self.host.redraw() + + def get_profiles(self): + return self.list_profile.get_selected_values() + + def get_jid(self): + return self.login_wid.get_edit_text() + + def getPassword(self): + return self.pass_wid.get_edit_text() + + def set_jid(self, jid_): + self.login_wid.set_edit_text(jid_) + self.current.login = jid_ + self.host.redraw() # FIXME: redraw should be avoided + + def set_password(self, password): + self.pass_wid.set_edit_text(password) + self.current.password = password + self.host.redraw() + + def on_profile_change(self, list_wid, widget=None, selected=None): + """This is called when a profile is selected in the profile list. + + @param list_wid: the List widget who sent the event + """ + self.update_connection_params() + focused = list_wid.focus + selected = focused.get_state() if focused is not None else False + if not selected: # profile was just unselected + return + focused.set_state( + False, invisible=True + ) # we don't want the widget to be selected until we are sure we can access it + + def authenticate_cb(data, cb_id, profile): + if C.bool(data.pop("validated", C.BOOL_FALSE)): + self.current.profile = profile + focused.set_state(True, invisible=True) + self.get_connection_params(profile) + self.host.redraw() + self.host.action_manager(data, callback=authenticate_cb, profile=profile) + + self.host.action_launch( + C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=focused.text + )