Mercurial > libervia-desktop-kivy
annotate src/cagou/core/profile_manager.py @ 58:7aa2ffff9067
chat: <img/> tag handling first draft:
We need to have several widgets to handle <img/> (label(s) + image(s)), which make sizing and positioning complicated.
To make things simpler, we use a simple trick when several widgets are present: we split the labels in as many labels as there are words, so we can take profit of the StackLayout.
The split is done after the XHTML is parsed, so after all the widgets are present, and is done only once. This means that label need to be reparsed to be splitted.
This is not perfect, but should be a reasonable solutions until we implement a real XHTML engine (probably CEF widget and Webview).
image sizing and alignment is not handled correcly now, should be fixed soon.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 28 Sep 2016 22:02:36 +0200 |
parents | 817a45e6d7e3 |
children | 1922506846be |
rev | line source |
---|---|
0 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client | |
5 # Copyright (C) 2016 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 | |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
21 from sat.core import log as logging |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
22 log = logging.getLogger(__name__) |
56
817a45e6d7e3
core (profile_manager): fixed bad import
Goffi <goffi@goffi.org>
parents:
16
diff
changeset
|
23 from .constants import Const as C |
0 | 24 from sat_frontends.quick_frontend.quick_profile_manager import QuickProfileManager |
25 from kivy.uix.boxlayout import BoxLayout | |
26 from kivy.uix import listview | |
27 from kivy.uix.button import Button | |
28 from kivy.uix.screenmanager import ScreenManager, Screen | |
29 from kivy.adapters import listadapter | |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
30 from kivy import properties |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
31 from cagou import G |
0 | 32 |
33 | |
34 class ProfileItem(listview.ListItemButton): | |
35 pass | |
36 | |
37 | |
38 class ProfileListAdapter(listadapter.ListAdapter): | |
39 | |
40 def __init__(self, pm, *args, **kwargs): | |
41 super(ProfileListAdapter, self).__init__(*args, **kwargs) | |
42 self.pm = pm | |
43 | |
44 def closeUI(self, xmlui): | |
45 self.pm.screen_manager.transition.direction = 'right' | |
46 self.pm.screen_manager.current = 'profiles' | |
47 | |
48 def showUI(self, xmlui): | |
49 xmlui.setCloseCb(self.closeUI) | |
50 if xmlui.type == 'popup': | |
51 xmlui.bind(on_touch_up=lambda obj, value: self.closeUI(xmlui)) | |
52 self.pm.xmlui_screen.clear_widgets() | |
53 self.pm.xmlui_screen.add_widget(xmlui) | |
54 self.pm.screen_manager.transition.direction = 'left' | |
55 self.pm.screen_manager.current = 'xmlui' | |
56 | |
57 def select_item_view(self, view): | |
58 def authenticate_cb(data, cb_id, profile): | |
59 if C.bool(data.pop('validated', C.BOOL_FALSE)): | |
60 super(ProfileListAdapter, self).select_item_view(view) | |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
61 G.host.actionManager(data, callback=authenticate_cb, ui_show_cb=self.showUI, profile=profile) |
0 | 62 |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
63 G.host.launchAction(C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=view.text) |
0 | 64 |
65 | |
66 class ConnectButton(Button): | |
4
440a743b58ee
Profile manager: Connect button is disabled when no profile is selected
Goffi <goffi@goffi.org>
parents:
2
diff
changeset
|
67 |
5
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
68 def __init__(self, profile_screen): |
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
69 self.profile_screen = profile_screen |
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
70 self.pm = profile_screen.pm |
4
440a743b58ee
Profile manager: Connect button is disabled when no profile is selected
Goffi <goffi@goffi.org>
parents:
2
diff
changeset
|
71 super(ConnectButton, self).__init__() |
0 | 72 |
73 | |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
74 class NewProfileScreen(Screen): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
75 profile_name = properties.ObjectProperty(None) |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
76 jid = properties.ObjectProperty(None) |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
77 password = properties.ObjectProperty(None) |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
78 error_msg = properties.StringProperty('') |
0 | 79 |
80 def __init__(self, pm): | |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
81 super(NewProfileScreen, self).__init__(name=u'new_profile') |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
82 self.pm = pm |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
83 |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
84 def onCreationFailure(self, failure): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
85 msg = [l for l in unicode(failure).split('\n') if l][-1] |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
86 self.error_msg = unicode(msg) |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
87 |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
88 def onCreationSuccess(self, profile): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
89 self.pm.profiles_screen.reload() |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
90 G.host.bridge.profileStartSession(self.password.text, profile, callback=lambda dummy: self._sessionStarted(profile), errback=self.onCreationFailure) |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
91 |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
92 def _sessionStarted(self, profile): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
93 jid = self.jid.text.strip() |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
94 G.host.bridge.setParam("JabberID", jid, "Connection", -1, profile) |
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
95 G.host.bridge.setParam("Password", self.password.text, "Connection", -1, profile) |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
96 self.pm.screen_manager.transition.direction = 'right' |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
97 self.pm.screen_manager.current = 'profiles' |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
98 |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
99 def doCreate(self): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
100 name = self.profile_name.text.strip() |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
101 # XXX: we use XMPP password for profile password to simplify |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
102 # if user want to change profile password, he can do it in preferences |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
103 G.host.bridge.asyncCreateProfile(name, self.password.text, callback=lambda: self.onCreationSuccess(name), errback=self.onCreationFailure) |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
104 |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
105 |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
106 class DeleteProfilesScreen(Screen): |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
107 |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
108 def __init__(self, pm): |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
109 self.pm = pm |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
110 super(DeleteProfilesScreen, self).__init__(name=u'delete_profiles') |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
111 |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
112 def doDelete(self): |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
113 """This method will delete *ALL* selected profiles""" |
5
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
114 to_delete = self.pm.getProfiles() |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
115 deleted = [0] |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
116 |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
117 def deleteInc(): |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
118 deleted[0] += 1 |
5
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
119 if deleted[0] == len(to_delete): |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
120 self.pm.profiles_screen.reload() |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
121 self.pm.screen_manager.transition.direction = 'right' |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
122 self.pm.screen_manager.current = 'profiles' |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
123 |
5
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
124 for profile in to_delete: |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
125 log.info(u"Deleteing profile [{}]".format(profile)) |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
126 G.host.bridge.asyncDeleteProfile(profile, callback=deleteInc, errback=deleteInc) |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
127 |
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
128 |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
129 class ProfilesScreen(Screen): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
130 layout = properties.ObjectProperty(None) |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
131 |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
132 def __init__(self, pm): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
133 self.pm = pm |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
134 profiles = G.host.bridge.getProfilesList() |
0 | 135 profiles.sort() |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
136 self.list_adapter = ProfileListAdapter(pm, |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
137 data=profiles, |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
138 cls=ProfileItem, |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
139 selection_mode='multiple', |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
140 allow_empty_selection=True, |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
141 ) |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
142 super(ProfilesScreen, self).__init__(name=u'profiles') |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
143 self.layout.add_widget(listview.ListView(adapter=self.list_adapter)) |
4
440a743b58ee
Profile manager: Connect button is disabled when no profile is selected
Goffi <goffi@goffi.org>
parents:
2
diff
changeset
|
144 connect_btn = ConnectButton(self) |
0 | 145 self.layout.add_widget(connect_btn) |
146 | |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
147 def reload(self): |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
148 """Reload profiles list""" |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
149 profiles = G.host.bridge.getProfilesList() |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
150 profiles.sort() |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
151 self.list_adapter.data = profiles |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
152 |
0 | 153 |
154 class ProfileManager(QuickProfileManager, BoxLayout): | |
155 | |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
156 def __init__(self, autoconnect=None): |
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
157 QuickProfileManager.__init__(self, G.host, autoconnect) |
0 | 158 BoxLayout.__init__(self, orientation="vertical") |
159 self.screen_manager = ScreenManager() | |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
160 self.profiles_screen = ProfilesScreen(self) |
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
161 self.new_profile_screen = NewProfileScreen(self) |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
162 self.delete_profiles_screen = DeleteProfilesScreen(self) |
0 | 163 self.xmlui_screen = Screen(name=u'xmlui') |
164 self.screen_manager.add_widget(self.profiles_screen) | |
165 self.screen_manager.add_widget(self.xmlui_screen) | |
1
189b76859110
Profile manager: new profile creation is handled
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
166 self.screen_manager.add_widget(self.new_profile_screen) |
2
8f9ed634a5eb
Profile manager: profile(s) deletion is handled
Goffi <goffi@goffi.org>
parents:
1
diff
changeset
|
167 self.screen_manager.add_widget(self.delete_profiles_screen) |
0 | 168 self.add_widget(self.screen_manager) |
169 | |
5
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
170 def getProfiles(self): |
33b619506832
profile manger: launch plug process when "Connect" button is pressed (full plugging is not working yet)
Goffi <goffi@goffi.org>
parents:
4
diff
changeset
|
171 return [pi.text for pi in self.profiles_screen.list_adapter.selection] |