Mercurial > libervia-desktop-kivy
comparison cagou/core/share_widget.py @ 336:b0c9017a1db7
core: added forgotten share_widget module
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 28 Dec 2019 16:09:54 +0100 |
parents | |
children | 38fd457b2158 |
comparison
equal
deleted
inserted
replaced
335:597cc207c8e7 | 336:b0c9017a1db7 |
---|---|
1 #!/usr/bin/python | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client | |
5 # Copyright (C) 2016-2019 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 | |
21 from pathlib import Path | |
22 from sat.core import log as logging | |
23 from sat.core.i18n import _ | |
24 from sat.tools.common import data_format | |
25 from sat_frontends.tools import jid | |
26 from kivy.uix.boxlayout import BoxLayout | |
27 from kivy.uix.behaviors import ButtonBehavior | |
28 from kivy.properties import StringProperty, DictProperty, ObjectProperty | |
29 from kivy.core.window import Window | |
30 from kivy.metrics import dp | |
31 from .common import ContactItem | |
32 from .constants import Const as C | |
33 from cagou import G | |
34 | |
35 | |
36 log = logging.getLogger(__name__) | |
37 | |
38 | |
39 PLUGIN_INFO = { | |
40 "name": _("share"), | |
41 "main": "Share", | |
42 "description": _("share a file"), | |
43 "icon_symbol": "share", | |
44 } | |
45 | |
46 class ShareContactItem(ButtonBehavior, ContactItem): | |
47 | |
48 def filterDataCb(self, data): | |
49 G.host.doAction('chat', jid.JID(self.jid), [self.profile]) | |
50 chat_wid = G.host.selected_widget | |
51 | |
52 if self.share_wid.type == 'text': | |
53 text = self.share_wid.data['text'] | |
54 chat_wid.message_input.text += text | |
55 else: | |
56 path = self.share_wid.data['path'] | |
57 chat_wid.transferFile(path, cleaning_cb=data.get('cleaning_cb')) | |
58 self.share_wid.close() | |
59 | |
60 def filterDataEb(self, failure_): | |
61 G.host.addNote( | |
62 _("file filter error"), | |
63 _("Can't apply filter to file: {msg}").format(msg=failure_), | |
64 level=C.XMLUI_DATA_LVL_ERROR) | |
65 | |
66 def on_press(self): | |
67 self.share_wid = G.host.getAncestorWidget(self, ShareWidget) | |
68 self.share_wid.getFilteredData(self.filterDataCb, self.filterDataEb) | |
69 | |
70 | |
71 class TextPreview(BoxLayout): | |
72 """Widget previewing shared text""" | |
73 text = StringProperty() | |
74 | |
75 | |
76 class ImagePreview(BoxLayout): | |
77 """Widget previewing shared image""" | |
78 path = StringProperty() | |
79 reduce_layout = ObjectProperty() | |
80 reduce_checkbox = ObjectProperty() | |
81 | |
82 def _checkImageCb(self, report_raw): | |
83 self.report = data_format.deserialise(report_raw) | |
84 if self.report['too_large']: | |
85 self.reduce_layout.opacity = 1 | |
86 self.reduce_layout.height = self.reduce_layout.minimum_height + dp(10) | |
87 self.reduce_layout.padding = [0, dp(5)] | |
88 | |
89 def _checkImageEb(self, failure_): | |
90 log.error(f"Can't check image: {failure_}") | |
91 | |
92 def on_path(self, wid, path): | |
93 G.host.bridge.imageCheck( | |
94 path, callback=self._checkImageCb, errback=self._checkImageEb) | |
95 | |
96 def resizeImage(self, data, callback, errback): | |
97 | |
98 def imageResizeCb(new_path): | |
99 new_path = Path(new_path) | |
100 log.debug(f"image {data['path']} resized at {new_path}") | |
101 data['path'] = new_path | |
102 data['cleaning_cb'] = lambda: new_path.unlink() | |
103 callback(data) | |
104 | |
105 path = data['path'] | |
106 width, height = self.report['recommended_size'] | |
107 G.host.bridge.imageResize( | |
108 path, width, height, | |
109 callback=imageResizeCb, | |
110 errback=errback | |
111 ) | |
112 | |
113 def getFilter(self): | |
114 if self.report['too_large'] and self.reduce_checkbox.active: | |
115 return self.resizeImage | |
116 else: | |
117 return lambda data, callback, errback: callback(data) | |
118 | |
119 | |
120 class GenericPreview(BoxLayout): | |
121 """Widget previewing shared image""" | |
122 path = StringProperty() | |
123 | |
124 | |
125 class ShareWidget(BoxLayout): | |
126 media_type = StringProperty() | |
127 data = DictProperty() | |
128 preview_box = ObjectProperty() | |
129 layout = ObjectProperty() | |
130 | |
131 def __init__(self, **kwargs): | |
132 super().__init__(**kwargs) | |
133 G.host.addListener("contactsFilled", self.onContactsFilled) | |
134 Window.bind(on_keyboard=self.key_input) | |
135 | |
136 def on_kv_post(self, wid): | |
137 self.type, self.subtype = self.media_type.split('/') | |
138 if self.type == 'text': | |
139 self.preview_box.add_widget(TextPreview(text=self.data['text'])) | |
140 elif self.type == 'image': | |
141 self.preview_box.add_widget(ImagePreview(path=self.data['path'])) | |
142 else: | |
143 self.preview_box.add_widget(GenericPreview(path=self.data['path'])) | |
144 self.addRosterContacts() | |
145 | |
146 def close(self): | |
147 G.host.closeUI() | |
148 | |
149 def on_parent(self, wid, parent): | |
150 if parent is None: | |
151 log.debug("removing contactsFilled listener") | |
152 G.host.removeListener("contactsFilled", self.onContactsFilled) | |
153 | |
154 | |
155 def addRosterContacts(self): | |
156 log.debug("starting addRosterContacts") | |
157 self.layout.clear_widgets() | |
158 for profile in G.host.profiles: | |
159 contact_list = G.host.contact_lists[profile] | |
160 for entity_jid in sorted(contact_list.roster): | |
161 item = ShareContactItem( | |
162 jid=entity_jid, | |
163 data=contact_list.getItem(entity_jid), | |
164 profile=profile, | |
165 ) | |
166 self.layout.add_widget(item) | |
167 | |
168 def onContactsFilled(self, profile): | |
169 log.debug("onContactsFilled event received") | |
170 self.addRosterContacts() | |
171 | |
172 def getFilteredData(self, callback, errback): | |
173 """Apply filter if suitable, and call callback with with modified data""" | |
174 try: | |
175 getFilter = self.preview_box.children[0].getFilter | |
176 except AttributeError: | |
177 callback(self.data) | |
178 else: | |
179 filter_ = getFilter() | |
180 filter_(self.data, callback=callback, errback=errback) | |
181 | |
182 def key_input(self, window, key, scancode, codepoint, modifier): | |
183 if key == 27: | |
184 self.close() | |
185 return True |