Mercurial > libervia-backend
comparison frontends/src/primitivus/profile_manager.py @ 1367:f71a0fc26886
merged branch frontends_multi_profiles
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 18 Mar 2015 10:52:28 +0100 |
parents | 948dc273ad93 |
children | 069ad98b360d |
comparison
equal
deleted
inserted
replaced
1295:1e3b1f9ad6e2 | 1367:f71a0fc26886 |
---|---|
16 | 16 |
17 # You should have received a copy of the GNU Affero General Public License | 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/>. | 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | 19 |
20 from sat.core.i18n import _ | 20 from sat.core.i18n import _ |
21 from sat.core import log as logging | |
22 log = logging.getLogger(__name__) | |
23 from sat_frontends.quick_frontend.quick_profile_manager import QuickProfileManager | |
21 from sat_frontends.primitivus.constants import Const as C | 24 from sat_frontends.primitivus.constants import Const as C |
25 from sat_frontends.primitivus.keys import action_key_map as a_key | |
26 from urwid_satext import sat_widgets | |
22 import urwid | 27 import urwid |
23 from urwid_satext.sat_widgets import AdvancedEdit, Password, List, InputDialog, ConfirmDialog, Alert | |
24 from sat_frontends.primitivus.keys import action_key_map as a_key | |
25 | 28 |
26 | 29 |
27 class ProfileManager(urwid.WidgetWrap): | 30 class ProfileManager(QuickProfileManager, urwid.WidgetWrap): |
28 | 31 |
29 def __init__(self, host): | 32 def __init__(self, host, autoconnect=None): |
30 self.host = host | 33 QuickProfileManager.__init__(self, host, autoconnect) |
31 #profiles list | |
32 profiles = self.host.bridge.getProfilesList() | |
33 profiles.sort() | |
34 | 34 |
35 #login & password box must be created before list because of onProfileChange | 35 #login & password box must be created before list because of onProfileChange |
36 self.login_wid = AdvancedEdit(_('Login:'), align='center') | 36 self.login_wid = sat_widgets.AdvancedEdit(_('Login:'), align='center') |
37 self.pass_wid = Password(_('Password:'), align='center') | 37 self.pass_wid = sat_widgets.Password(_('Password:'), align='center') |
38 | 38 |
39 self.selected_profile = None # allow to reselect the previous selection until the profile is authenticated | 39 style = ['no_first_select'] |
40 style = ['single'] | 40 profiles = host.bridge.getProfilesList() |
41 if self.host.options.profile: | 41 profiles.sort() |
42 style.append('no_first_select') | 42 self.list_profile = sat_widgets.List(profiles, style=style, align='center', on_change=self.onProfileChange) |
43 self.list_profile = List(profiles, style=style, align='center', on_change=self.onProfileChange) | |
44 | 43 |
45 #new & delete buttons | 44 #new & delete buttons |
46 buttons = [urwid.Button(_("New"), self.onNewProfile), | 45 buttons = [urwid.Button(_("New"), self.onNewProfile), |
47 urwid.Button(_("Delete"), self.onDeleteProfile)] | 46 urwid.Button(_("Delete"), self.onDeleteProfile)] |
48 buttons_flow = urwid.GridFlow(buttons, max([len(button.get_label()) for button in buttons])+4, 1, 1, 'center') | 47 buttons_flow = urwid.GridFlow(buttons, max([len(button.get_label()) for button in buttons])+4, 1, 1, 'center') |
49 | 48 |
50 #second part: login information: | 49 #second part: login information: |
51 divider = urwid.Divider('-') | 50 divider = urwid.Divider('-') |
52 | 51 |
53 #connect button | 52 #connect button |
54 connect_button = urwid.Button(_("Connect"), self.onConnectProfile) | 53 connect_button = sat_widgets.CustomButton(_("Connect"), self.onConnectProfiles, align='center') |
55 | 54 |
56 #we now build the widget | 55 #we now build the widget |
57 list_walker = urwid.SimpleFocusListWalker([buttons_flow,self.list_profile,divider,self.login_wid, self.pass_wid, connect_button]) | 56 list_walker = urwid.SimpleFocusListWalker([buttons_flow,self.list_profile, divider, self.login_wid, self.pass_wid, connect_button]) |
58 frame_body = urwid.ListBox(list_walker) | 57 frame_body = urwid.ListBox(list_walker) |
59 frame = urwid.Frame(frame_body,urwid.AttrMap(urwid.Text(_("Profile Manager"),align='center'),'title')) | 58 frame = urwid.Frame(frame_body,urwid.AttrMap(urwid.Text(_("Profile Manager"),align='center'),'title')) |
60 self.main_widget = urwid.LineBox(frame) | 59 self.main_widget = urwid.LineBox(frame) |
61 urwid.WidgetWrap.__init__(self, self.main_widget) | 60 urwid.WidgetWrap.__init__(self, self.main_widget) |
61 | |
62 self.go(autoconnect) | |
63 | |
62 | 64 |
63 def keypress(self, size, key): | 65 def keypress(self, size, key): |
64 if key == a_key['APP_QUIT']: | 66 if key == a_key['APP_QUIT']: |
65 self.host.onExit() | 67 self.host.onExit() |
66 raise urwid.ExitMainLoop() | 68 raise urwid.ExitMainLoop() |
78 list_box.set_focus(current_focus, 'above' if focus_diff == 1 else 'below') | 80 list_box.set_focus(current_focus, 'above' if focus_diff == 1 else 'below') |
79 list_box._invalidate() | 81 list_box._invalidate() |
80 return | 82 return |
81 return super(ProfileManager, self).keypress(size, key) | 83 return super(ProfileManager, self).keypress(size, key) |
82 | 84 |
83 def __refillProfiles(self): | |
84 """Update the list of profiles""" | |
85 profiles = self.host.bridge.getProfilesList() | |
86 profiles.sort() | |
87 self.list_profile.changeValues(profiles) | |
88 | |
89 def cancelDialog(self, button): | 85 def cancelDialog(self, button): |
90 self.host.removePopUp() | 86 self.host.removePopUp() |
91 | 87 |
92 def newProfile(self, button, edit): | 88 def newProfile(self, button, edit): |
93 """Create the profile""" | 89 """Create the profile""" |
94 name = edit.get_edit_text() | 90 name = edit.get_edit_text() |
95 self.host.bridge.asyncCreateProfile(name, callback=lambda: self._newProfileCreated(name), errback=self._profileCreationFailure) | 91 self.host.bridge.asyncCreateProfile(name, callback=lambda: self.newProfileCreated(name), errback=self.profileCreationFailure) |
96 | 92 |
97 def _newProfileCreated(self, name): | 93 def newProfileCreated(self, profile): |
98 self.__refillProfiles() | |
99 #We select the profile created in the list | |
100 self.list_profile.selectValue(name) | |
101 self.host.removePopUp() | 94 self.host.removePopUp() |
95 self.refillProfiles() | |
96 self.list_profile.selectValue(profile) | |
97 self.current.profile=profile | |
98 self.getConnectionParams(profile) | |
102 self.host.redraw() | 99 self.host.redraw() |
103 | 100 |
104 def _profileCreationFailure(self, reason): | 101 def profileCreationFailure(self, reason): |
105 self.host.removePopUp() | 102 self.host.removePopUp() |
106 if reason == "ConflictError": | 103 message = self._getErrorMessage(reason) |
107 message = _("A profile with this name already exists") | 104 self.alert(_("Can't create profile"), message) |
108 elif reason == "CancelError": | |
109 message = _("Profile creation cancelled by backend") | |
110 else: | |
111 message = _("Unknown reason (%s)") % reason | |
112 popup = Alert(_("Can't create profile"), message, ok_cb=self.host.removePopUp) | |
113 self.host.showPopUp(popup) | |
114 | 105 |
115 def deleteProfile(self, button): | 106 def deleteProfile(self, button): |
116 profile_name = self.list_profile.getSelectedValue() | 107 self._deleteProfile() |
117 if profile_name: | |
118 self.host.bridge.asyncDeleteProfile(profile_name, callback=self.__refillProfiles) | |
119 self.host.removePopUp() | 108 self.host.removePopUp() |
120 | 109 |
121 def onNewProfile(self, e): | 110 def onNewProfile(self, e): |
122 pop_up_widget = InputDialog(_("New profile"), _("Please enter a new profile name"), cancel_cb=self.cancelDialog, ok_cb=self.newProfile) | 111 pop_up_widget = sat_widgets.InputDialog(_("New profile"), _("Please enter a new profile name"), cancel_cb=self.cancelDialog, ok_cb=self.newProfile) |
123 self.host.showPopUp(pop_up_widget) | 112 self.host.showPopUp(pop_up_widget) |
124 | 113 |
125 def onDeleteProfile(self, e): | 114 def onDeleteProfile(self, e): |
126 pop_up_widget = ConfirmDialog(_("Are you sure you want to delete the profile %s ?") % self.list_profile.getSelectedValue(), no_cb=self.cancelDialog, yes_cb=self.deleteProfile) | 115 if self.current.profile: |
127 self.host.showPopUp(pop_up_widget) | 116 pop_up_widget = sat_widgets.ConfirmDialog(_("Are you sure you want to delete the profile {} ?").format(self.current.profile), no_cb=self.cancelDialog, yes_cb=self.deleteProfile) |
117 self.host.showPopUp(pop_up_widget) | |
128 | 118 |
129 def getXMPPParams(self, profile): | 119 def onConnectProfiles(self, button): |
130 """This is called from PrimitivusApp.launchAction when the profile has been authenticated. | 120 """Connect the profiles and start the main widget |
131 | 121 |
132 @param profile: %(doc_profile)s | 122 @param button: the connect button |
133 """ | 123 """ |
134 def setJID(jabberID): | 124 self._onConnectProfiles() |
135 self.login_wid.set_edit_text(jabberID) | |
136 self.host.redraw() | |
137 | 125 |
138 def setPassword(password): | 126 def resetFields(self): |
139 self.pass_wid.set_edit_text(password) | 127 """Set profile to None, and reset fields""" |
140 self.host.redraw() | 128 super(ProfileManager, self).resetFields() |
129 self.list_profile.unselectAll(invisible=True) | |
141 | 130 |
142 self.list_profile.selectValue(profile, move_focus=False) | 131 def setProfiles(self, profiles): |
143 self.selected_profile = profile | 132 """Update the list of profiles""" |
144 self.host.bridge.asyncGetParamA("JabberID", "Connection", profile_key=profile, callback=setJID, errback=self.getParamError) | 133 self.list_profile.changeValues(profiles) |
145 self.host.bridge.asyncGetParamA("Password", "Connection", profile_key=profile, callback=setPassword, errback=self.getParamError) | 134 self.host.redraw() |
135 | |
136 def getProfiles(self): | |
137 return self.list_profile.getSelectedValues() | |
138 | |
139 def getJID(self): | |
140 return self.login_wid.get_edit_text() | |
141 | |
142 def getPassword(self): | |
143 return self.pass_wid.get_edit_text() | |
144 | |
145 def setJID(self, jid_): | |
146 self.login_wid.set_edit_text(jid_) | |
147 self.current.login = jid_ | |
148 self.host.redraw() # FIXME: redraw should be avoided | |
149 | |
150 def setPassword(self, password): | |
151 self.pass_wid.set_edit_text(password) | |
152 self.current.password = password | |
153 self.host.redraw() | |
154 | |
155 def alert(self, title, message): | |
156 popup = sat_widgets.Alert(title, message, ok_cb=self.host.removePopUp) | |
157 self.host.showPopUp(popup) | |
146 | 158 |
147 def onProfileChange(self, list_wid): | 159 def onProfileChange(self, list_wid): |
148 """This is called when a profile is selected in the profile list. | 160 """This is called when a profile is selected in the profile list. |
149 | 161 |
150 @param list_wid: the List widget who sent the event | 162 @param list_wid: the List widget who sent the event |
151 """ | 163 """ |
152 profile_name = list_wid.getSelectedValue() | 164 self.updateConnectionParams() |
153 if not profile_name or profile_name == self.selected_profile: | 165 focused = list_wid.focus |
154 return # avoid infinite loop | 166 selected = focused.getState() |
155 if self.selected_profile: | 167 if not selected: # profile was just unselected |
156 list_wid.selectValue(self.selected_profile, move_focus=False) | 168 return |
157 else: | 169 focused.setState(False, invisible=True) # we don't want the widget to be selected until we are sure we can access it |
158 list_wid.unselectAll(invisible=True) | 170 def authenticate_cb(callback_id, data, profile): |
159 self.host.redraw() | 171 if C.bool(data['validated']): |
160 self.host.profile = profile_name # FIXME: EXTREMELY DIRTY, needed for sat_frontends.tools.xmlui.XMLUI._xmluiLaunchAction | 172 self.current.profile = profile |
161 self.host.launchAction(C.AUTHENTICATE_PROFILE_ID, {'caller': 'profile_manager'}, profile_key=profile_name) | 173 focused.setState(True, invisible=True) |
174 self.getConnectionParams(profile) | |
175 self.host.redraw() | |
176 self.host.launchAction(C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=focused.text) | |
162 | 177 |
163 def onConnectProfile(self, button): | |
164 profile_name = self.list_profile.getSelectedValue() | |
165 assert(profile_name == self.selected_profile) # if not, there's a bug somewhere... | |
166 if not profile_name: | |
167 pop_up_widget = Alert(_('No profile selected'), _('You need to create and select a profile before connecting'), ok_cb=self.cancelDialog) | |
168 self.host.showPopUp(pop_up_widget) | |
169 elif profile_name[0] == '@': | |
170 pop_up_widget = Alert(_('Bad profile name'), _("A profile name can't start with a @"), ok_cb=self.cancelDialog) | |
171 self.host.showPopUp(pop_up_widget) | |
172 else: | |
173 profile = self.host.bridge.getProfileName(profile_name) | |
174 assert(profile) | |
175 #TODO: move this to quick_app | |
176 self.host.bridge.asyncGetParamA("JabberID", "Connection", profile_key=profile, | |
177 callback=lambda old_jid: self.__old_jidReceived(old_jid, profile), errback=self.getParamError) | |
178 | |
179 def __old_jidReceived(self, old_jid, profile): | |
180 self.host.bridge.asyncGetParamA("Password", "Connection", profile_key=profile, | |
181 callback=lambda old_pass: self.__old_passReceived(old_jid, old_pass, profile), errback=self.getParamError) | |
182 | |
183 def __old_passReceived(self, old_jid, old_pass, profile): | |
184 """Check if we have new jid/pass, save them if it is the case, and plug profile""" | |
185 new_jid = self.login_wid.get_edit_text() | |
186 new_pass = self.pass_wid.get_edit_text() | |
187 | |
188 if old_jid != new_jid: | |
189 self.host.bridge.setParam("JabberID", new_jid, "Connection", profile_key=profile) | |
190 if old_pass != new_pass: | |
191 self.host.bridge.setParam("Password", new_pass, "Connection", profile_key=profile) | |
192 self.host.plug_profile(profile) | |
193 | |
194 def getParamError(self, ignore): | |
195 popup = Alert("Error", _("Can't get profile parameter"), ok_cb=self.host.removePopUp) | |
196 self.host.showPopUp(popup) |