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)