Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
4075:47401850dec6 | 4076:b620a8e882e1 |
---|---|
1 #!/usr/bin/env python3 | |
2 | |
3 | |
4 # Libervia TUI | |
5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) | |
6 | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 from libervia.backend.core.i18n import _ | |
21 from libervia.backend.core import log as logging | |
22 | |
23 log = logging.getLogger(__name__) | |
24 from libervia.frontends.quick_frontend.quick_profile_manager import QuickProfileManager | |
25 from libervia.tui.constants import Const as C | |
26 from libervia.tui.keys import action_key_map as a_key | |
27 from urwid_satext import sat_widgets | |
28 import urwid | |
29 | |
30 | |
31 class ProfileManager(QuickProfileManager, urwid.WidgetWrap): | |
32 def __init__(self, host, autoconnect=None): | |
33 QuickProfileManager.__init__(self, host, autoconnect) | |
34 | |
35 # login & password box must be created before list because of on_profile_change | |
36 self.login_wid = sat_widgets.AdvancedEdit(_("Login:"), align="center") | |
37 self.pass_wid = sat_widgets.Password(_("Password:"), align="center") | |
38 | |
39 style = ["no_first_select"] | |
40 profiles = host.bridge.profiles_list_get() | |
41 profiles.sort() | |
42 self.list_profile = sat_widgets.List( | |
43 profiles, style=style, align="center", on_change=self.on_profile_change | |
44 ) | |
45 | |
46 # new & delete buttons | |
47 buttons = [ | |
48 urwid.Button(_("New"), self.on_new_profile), | |
49 urwid.Button(_("Delete"), self.on_delete_profile), | |
50 ] | |
51 buttons_flow = urwid.GridFlow( | |
52 buttons, | |
53 max([len(button.get_label()) for button in buttons]) + 4, | |
54 1, | |
55 1, | |
56 "center", | |
57 ) | |
58 | |
59 # second part: login information: | |
60 divider = urwid.Divider("-") | |
61 | |
62 # connect button | |
63 connect_button = sat_widgets.CustomButton( | |
64 _("Connect"), self.on_connect_profiles, align="center" | |
65 ) | |
66 | |
67 # we now build the widget | |
68 list_walker = urwid.SimpleFocusListWalker( | |
69 [ | |
70 buttons_flow, | |
71 self.list_profile, | |
72 divider, | |
73 self.login_wid, | |
74 self.pass_wid, | |
75 connect_button, | |
76 ] | |
77 ) | |
78 frame_body = urwid.ListBox(list_walker) | |
79 frame = urwid.Frame( | |
80 frame_body, | |
81 urwid.AttrMap(urwid.Text(_("Profile Manager"), align="center"), "title"), | |
82 ) | |
83 self.main_widget = urwid.LineBox(frame) | |
84 urwid.WidgetWrap.__init__(self, self.main_widget) | |
85 | |
86 self.go(autoconnect) | |
87 | |
88 def keypress(self, size, key): | |
89 if key == a_key["APP_QUIT"]: | |
90 self.host.on_exit() | |
91 raise urwid.ExitMainLoop() | |
92 elif key in (a_key["FOCUS_UP"], a_key["FOCUS_DOWN"]): | |
93 focus_diff = 1 if key == a_key["FOCUS_DOWN"] else -1 | |
94 list_box = self.main_widget.base_widget.body | |
95 current_focus = list_box.body.get_focus()[1] | |
96 if current_focus is None: | |
97 return | |
98 while True: | |
99 current_focus += focus_diff | |
100 if current_focus < 0 or current_focus >= len(list_box.body): | |
101 break | |
102 if list_box.body[current_focus].selectable(): | |
103 list_box.set_focus( | |
104 current_focus, "above" if focus_diff == 1 else "below" | |
105 ) | |
106 list_box._invalidate() | |
107 return | |
108 return super(ProfileManager, self).keypress(size, key) | |
109 | |
110 def cancel_dialog(self, button): | |
111 self.host.remove_pop_up() | |
112 | |
113 def new_profile(self, button, edit): | |
114 """Create the profile""" | |
115 name = edit.get_edit_text() | |
116 self.host.bridge.profile_create( | |
117 name, | |
118 callback=lambda: self.new_profile_created(name), | |
119 errback=self.profile_creation_failure, | |
120 ) | |
121 | |
122 def new_profile_created(self, profile): | |
123 # new profile will be selected, and a selected profile assume the session is started | |
124 self.host.bridge.profile_start_session( | |
125 "", | |
126 profile, | |
127 callback=lambda __: self.new_profile_session_started(profile), | |
128 errback=self.profile_creation_failure, | |
129 ) | |
130 | |
131 def new_profile_session_started(self, profile): | |
132 self.host.remove_pop_up() | |
133 self.refill_profiles() | |
134 self.list_profile.select_value(profile) | |
135 self.current.profile = profile | |
136 self.get_connection_params(profile) | |
137 self.host.redraw() | |
138 | |
139 def profile_creation_failure(self, reason): | |
140 self.host.remove_pop_up() | |
141 message = self._get_error_message(reason) | |
142 self.host.alert(_("Can't create profile"), message) | |
143 | |
144 def delete_profile(self, button): | |
145 self._delete_profile() | |
146 self.host.remove_pop_up() | |
147 | |
148 def on_new_profile(self, e): | |
149 pop_up_widget = sat_widgets.InputDialog( | |
150 _("New profile"), | |
151 _("Please enter a new profile name"), | |
152 cancel_cb=self.cancel_dialog, | |
153 ok_cb=self.new_profile, | |
154 ) | |
155 self.host.show_pop_up(pop_up_widget) | |
156 | |
157 def on_delete_profile(self, e): | |
158 if self.current.profile: | |
159 pop_up_widget = sat_widgets.ConfirmDialog( | |
160 _("Are you sure you want to delete the profile {} ?").format( | |
161 self.current.profile | |
162 ), | |
163 no_cb=self.cancel_dialog, | |
164 yes_cb=self.delete_profile, | |
165 ) | |
166 self.host.show_pop_up(pop_up_widget) | |
167 | |
168 def on_connect_profiles(self, button): | |
169 """Connect the profiles and start the main widget | |
170 | |
171 @param button: the connect button | |
172 """ | |
173 self._on_connect_profiles() | |
174 | |
175 def reset_fields(self): | |
176 """Set profile to None, and reset fields""" | |
177 super(ProfileManager, self).reset_fields() | |
178 self.list_profile.unselect_all(invisible=True) | |
179 | |
180 def set_profiles(self, profiles): | |
181 """Update the list of profiles""" | |
182 self.list_profile.change_values(profiles) | |
183 self.host.redraw() | |
184 | |
185 def get_profiles(self): | |
186 return self.list_profile.get_selected_values() | |
187 | |
188 def get_jid(self): | |
189 return self.login_wid.get_edit_text() | |
190 | |
191 def getPassword(self): | |
192 return self.pass_wid.get_edit_text() | |
193 | |
194 def set_jid(self, jid_): | |
195 self.login_wid.set_edit_text(jid_) | |
196 self.current.login = jid_ | |
197 self.host.redraw() # FIXME: redraw should be avoided | |
198 | |
199 def set_password(self, password): | |
200 self.pass_wid.set_edit_text(password) | |
201 self.current.password = password | |
202 self.host.redraw() | |
203 | |
204 def on_profile_change(self, list_wid, widget=None, selected=None): | |
205 """This is called when a profile is selected in the profile list. | |
206 | |
207 @param list_wid: the List widget who sent the event | |
208 """ | |
209 self.update_connection_params() | |
210 focused = list_wid.focus | |
211 selected = focused.get_state() if focused is not None else False | |
212 if not selected: # profile was just unselected | |
213 return | |
214 focused.set_state( | |
215 False, invisible=True | |
216 ) # we don't want the widget to be selected until we are sure we can access it | |
217 | |
218 def authenticate_cb(data, cb_id, profile): | |
219 if C.bool(data.pop("validated", C.BOOL_FALSE)): | |
220 self.current.profile = profile | |
221 focused.set_state(True, invisible=True) | |
222 self.get_connection_params(profile) | |
223 self.host.redraw() | |
224 self.host.action_manager(data, callback=authenticate_cb, profile=profile) | |
225 | |
226 self.host.action_launch( | |
227 C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=focused.text | |
228 ) |