Mercurial > libervia-web
comparison src/browser/sat_browser/widget.py @ 679:a90cc8fc9605
merged branch frontends_multi_profiles
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 18 Mar 2015 16:15:18 +0100 |
parents | src/browser/sat_browser/panels.py@3eb3a2c0c011 src/browser/sat_browser/panels.py@849ffb24d5bf |
children | 9877607c719a |
comparison
equal
deleted
inserted
replaced
590:1bffc4c244c3 | 679:a90cc8fc9605 |
---|---|
1 #!/usr/bin/python | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # Libervia: a Salut à Toi frontend | |
5 # Copyright (C) 2011, 2012, 2013, 2014 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 import pyjd # this is dummy in pyjs | |
21 from sat.core.log import getLogger | |
22 log = getLogger(__name__) | |
23 | |
24 from sat.core.i18n import D_ | |
25 | |
26 from pyjamas.ui.VerticalPanel import VerticalPanel | |
27 from pyjamas.ui.HorizontalPanel import HorizontalPanel | |
28 from pyjamas.ui.Button import Button | |
29 from pyjamas.ui.Frame import Frame | |
30 from pyjamas import DOM | |
31 | |
32 | |
33 import dialog | |
34 import libervia_widget | |
35 from constants import Const as C | |
36 from sat_frontends.quick_frontend import quick_widgets | |
37 from sat_frontends.tools import host_listener | |
38 | |
39 | |
40 # class UniBoxPanel(HorizontalPanel): | |
41 # """Panel containing the UniBox""" | |
42 # | |
43 # def __init__(self, host): | |
44 # HorizontalPanel.__init__(self) | |
45 # self.host = host | |
46 # self.setStyleName('uniBoxPanel') | |
47 # self.unibox = None | |
48 # | |
49 # def refresh(self): | |
50 # """Enable or disable this panel. Contained widgets are created when necessary.""" | |
51 # enable = self.host.getCachedParam(C.COMPOSITION_KEY, C.ENABLE_UNIBOX_PARAM) == 'true' | |
52 # self.setVisible(enable) | |
53 # if enable and not self.unibox: | |
54 # self.button = Button('<img src="media/icons/tango/actions/32/format-text-italic.png" class="richTextIcon"/>') | |
55 # self.button.setTitle('Open the rich text editor') | |
56 # self.button.addStyleName('uniBoxButton') | |
57 # self.add(self.button) | |
58 # self.unibox = UniBox(self.host) | |
59 # self.add(self.unibox) | |
60 # self.setCellWidth(self.unibox, '100%') | |
61 # self.button.addClickListener(self.openRichMessageEditor) | |
62 # self.unibox.addKey("@@: ") | |
63 # self.unibox.onSelectedChange(self.host.getSelected()) | |
64 # | |
65 # def openRichMessageEditor(self): | |
66 # """Open the rich text editor.""" | |
67 # self.button.setVisible(False) | |
68 # self.unibox.setVisible(False) | |
69 # self.setCellWidth(self.unibox, '0px') | |
70 # self.host.panel._contactsMove(self) | |
71 # | |
72 # def afterEditCb(): | |
73 # Window.removeWindowResizeListener(self) | |
74 # self.host.panel._contactsMove(self.host.panel._hpanel) | |
75 # self.setCellWidth(self.unibox, '100%') | |
76 # self.button.setVisible(True) | |
77 # self.unibox.setVisible(True) | |
78 # self.host.resize() | |
79 # | |
80 # richtext.RichMessageEditor.getOrCreate(self.host, self, afterEditCb) | |
81 # Window.addWindowResizeListener(self) | |
82 # self.host.resize() | |
83 # | |
84 # def onWindowResized(self, width, height): | |
85 # right = self.host.panel.menu.getAbsoluteLeft() + self.host.panel.menu.getOffsetWidth() | |
86 # left = self.host.panel._contacts.getAbsoluteLeft() + self.host.panel._contacts.getOffsetWidth() | |
87 # ideal_width = right - left - 40 | |
88 # self.host.richtext.setWidth("%spx" % ideal_width) | |
89 | |
90 | |
91 | |
92 # class UniBox(MessageBox, MouseHandler): # AutoCompleteTextBox): | |
93 # """This text box is used as a main typing point, for message, microblog, etc""" | |
94 # | |
95 # def __init__(self, host): | |
96 # MessageBox.__init__(self, host) | |
97 # #AutoCompleteTextBox.__init__(self) | |
98 # self.setStyleName('uniBox') | |
99 # # FIXME | |
100 # # host.addSelectedListener(self.onSelectedChange) | |
101 # | |
102 # def addKey(self, key): | |
103 # return | |
104 # #self.getCompletionItems().completions.append(key) | |
105 # | |
106 # def removeKey(self, key): | |
107 # return | |
108 # # TODO: investigate why AutoCompleteTextBox doesn't work here, | |
109 # # maybe it can work on a TextBox but no TextArea. Remove addKey | |
110 # # and removeKey methods if they don't serve anymore. | |
111 # try: | |
112 # self.getCompletionItems().completions.remove(key) | |
113 # except KeyError: | |
114 # log.warning("trying to remove an unknown key") | |
115 # | |
116 # def _getTarget(self, txt): | |
117 # """ Say who will receive the messsage | |
118 # @return: a tuple (selected, target_type, target info) with: | |
119 # - target_hook: None if we use the selected widget, (msg, data) if we have a hook (e.g. "@@: " for a public blog), where msg is the parsed message (i.e. without the "hook key: "@@: bla" become ("bla", None)) | |
120 # - target_type: one of PUBLIC, GROUP, ONE2ONE, STATUS, MISC | |
121 # - msg: HTML message which will appear in the privacy warning banner """ | |
122 # target = self._selected_cache | |
123 # | |
124 # def getSelectedOrStatus(): | |
125 # if target and target.isSelectable(): | |
126 # _type, msg = target.getWarningData() | |
127 # target_hook = None # we use the selected widget, not a hook | |
128 # else: | |
129 # _type, msg = "STATUS", "This will be your new status message" | |
130 # target_hook = (txt, None) | |
131 # return (target_hook, _type, msg) | |
132 # | |
133 # if not txt.startswith('@'): | |
134 # target_hook, _type, msg = getSelectedOrStatus() | |
135 # elif txt.startswith('@@: '): | |
136 # _type = "PUBLIC" | |
137 # msg = MicroblogPanel.warning_msg_public | |
138 # target_hook = (txt[4:], None) | |
139 # elif txt.startswith('@'): | |
140 # _end = txt.find(': ') | |
141 # if _end == -1: | |
142 # target_hook, _type, msg = getSelectedOrStatus() | |
143 # else: | |
144 # group = txt[1:_end] # only one target group is managed for the moment | |
145 # if not group or not group in self.host.contact_panel.getGroups(): | |
146 # # the group doesn't exists, we ignore the key | |
147 # group = None | |
148 # target_hook, _type, msg = getSelectedOrStatus() | |
149 # else: | |
150 # _type = "GROUP" | |
151 # msg = MicroblogPanel.warning_msg_group % group | |
152 # target_hook = (txt[_end + 2:], group) | |
153 # else: | |
154 # log.error("Unknown target") | |
155 # target_hook, _type, msg = getSelectedOrStatus() | |
156 # | |
157 # return (target_hook, _type, msg) | |
158 # | |
159 # def onKeyPress(self, sender, keycode, modifiers): | |
160 # _txt = self.getText() | |
161 # target_hook, type_, msg = self._getTarget(_txt) | |
162 # | |
163 # if keycode == KEY_ENTER: | |
164 # if _txt: | |
165 # if target_hook: | |
166 # parsed_txt, data = target_hook | |
167 # self.host.send([(type_, data)], parsed_txt) | |
168 # self.host._updateInputHistory(_txt) | |
169 # self.setText('') | |
170 # self.host.showWarning(None, None) | |
171 # else: | |
172 # self.host.showWarning(type_, msg) | |
173 # MessageBox.onKeyPress(self, sender, keycode, modifiers) | |
174 # | |
175 # def getTargetAndData(self): | |
176 # """For external use, to get information about the (hypothetical) message | |
177 # that would be sent if we press Enter right now in the unibox. | |
178 # @return a tuple (target, data) with: | |
179 # - data: what would be the content of the message (body) | |
180 # - target: JID, group with the prefix "@" or the public entity "@@" | |
181 # """ | |
182 # _txt = self.getText() | |
183 # target_hook, _type, _msg = self._getTarget(_txt) | |
184 # if target_hook: | |
185 # data, target = target_hook | |
186 # if target is None: | |
187 # return target_hook | |
188 # return (data, "@%s" % (target if target != "" else "@")) | |
189 # if isinstance(self._selected_cache, MicroblogPanel): | |
190 # groups = self._selected_cache.accepted_groups | |
191 # target = "@%s" % (groups[0] if len(groups) > 0 else "@") | |
192 # if len(groups) > 1: | |
193 # Window.alert("Sole the first group of the selected panel is taken in consideration: '%s'" % groups[0]) | |
194 # # elif isinstance(self._selected_cache, ChatPanel): # FIXME | |
195 # # target = self._selected_cache.target | |
196 # else: | |
197 # target = None | |
198 # return (_txt, target) | |
199 # | |
200 # def onWidgetClosed(self, lib_wid): | |
201 # """Called when a libervia widget is closed""" | |
202 # if self._selected_cache == lib_wid: | |
203 # self.onSelectedChange(None) | |
204 # | |
205 # """def complete(self): | |
206 # | |
207 # #self.visible=False #XXX: self.visible is not unset in pyjamas when ENTER is pressed and a completion is done | |
208 # #XXX: fixed directly on pyjamas, if the patch is accepted, no need to walk around this | |
209 # return AutoCompleteTextBox.complete(self)""" | |
210 | |
211 | |
212 class WebWidget(quick_widgets.QuickWidget, libervia_widget.LiberviaWidget): | |
213 """ (mini)browser like widget """ | |
214 | |
215 def __init__(self, host, target, show_url=True, profiles=None): | |
216 """ | |
217 @param host: SatWebFrontend instance | |
218 @param target: url to open | |
219 """ | |
220 quick_widgets.QuickWidget.__init__(self, host, target, C.PROF_KEY_NONE) | |
221 libervia_widget.LiberviaWidget.__init__(self, host) | |
222 self._vpanel = VerticalPanel() | |
223 self._vpanel.setSize('100%', '100%') | |
224 self._url = dialog.ExtTextBox(enter_cb=self.onUrlClick) | |
225 self._url.setText(target or "") | |
226 self._url.setWidth('100%') | |
227 if show_url: | |
228 hpanel = HorizontalPanel() | |
229 hpanel.add(self._url) | |
230 btn = Button("Go", self.onUrlClick) | |
231 hpanel.setCellWidth(self._url, "100%") | |
232 hpanel.add(btn) | |
233 self._vpanel.add(hpanel) | |
234 self._vpanel.setCellHeight(hpanel, '20px') | |
235 self._frame = Frame(target or "") | |
236 self._frame.setSize('100%', '100%') | |
237 DOM.setStyleAttribute(self._frame.getElement(), "position", "relative") | |
238 self._vpanel.add(self._frame) | |
239 self.setWidget(self._vpanel) | |
240 | |
241 def onUrlClick(self, sender): | |
242 url = self._url.getText() | |
243 scheme_end = url.find(':') | |
244 scheme = "" if scheme_end == -1 else url[:scheme_end] | |
245 if scheme not in C.WEB_PANEL_SCHEMES: | |
246 url = "http://" + url | |
247 self._frame.setUrl(url) | |
248 | |
249 | |
250 ## Menu | |
251 | |
252 def hostReady(host): | |
253 def onWebWidget(): | |
254 web_widget = host.displayWidget(WebWidget, C.WEB_PANEL_DEFAULT_URL) | |
255 host.setSelected(web_widget) | |
256 | |
257 def gotMenus(): | |
258 host.menus.addMenu(C.MENU_GLOBAL, (D_(u"General"), D_(u"Web widget")), callback=onWebWidget) | |
259 host.addListener('gotMenus', gotMenus) | |
260 | |
261 host_listener.addListener(hostReady) |