view src/browser/sat_browser/widget.py @ 685:9877607c719a

2015 copyright dates update
author Goffi <goffi@goffi.org>
date Mon, 30 Mar 2015 10:28:47 +0200
parents a90cc8fc9605
children c2f22ca12e23
line wrap: on
line source

#!/usr/bin/python
# -*- coding: utf-8 -*-

# Libervia: a Salut à Toi frontend
# Copyright (C) 2011, 2012, 2013, 2014, 2015 Jérôme Poisson <goffi@goffi.org>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import pyjd  # this is dummy in pyjs
from sat.core.log import getLogger
log = getLogger(__name__)

from sat.core.i18n import D_

from pyjamas.ui.VerticalPanel import VerticalPanel
from pyjamas.ui.HorizontalPanel import HorizontalPanel
from pyjamas.ui.Button import Button
from pyjamas.ui.Frame import Frame
from pyjamas import DOM


import dialog
import libervia_widget
from constants import Const as C
from sat_frontends.quick_frontend import quick_widgets
from sat_frontends.tools import host_listener


# class UniBoxPanel(HorizontalPanel):
#     """Panel containing the UniBox"""
#
#     def __init__(self, host):
#         HorizontalPanel.__init__(self)
#         self.host = host
#         self.setStyleName('uniBoxPanel')
#         self.unibox = None
#
#     def refresh(self):
#         """Enable or disable this panel. Contained widgets are created when necessary."""
#         enable = self.host.getCachedParam(C.COMPOSITION_KEY, C.ENABLE_UNIBOX_PARAM) == 'true'
#         self.setVisible(enable)
#         if enable and not self.unibox:
#             self.button = Button('<img src="media/icons/tango/actions/32/format-text-italic.png" class="richTextIcon"/>')
#             self.button.setTitle('Open the rich text editor')
#             self.button.addStyleName('uniBoxButton')
#             self.add(self.button)
#             self.unibox = UniBox(self.host)
#             self.add(self.unibox)
#             self.setCellWidth(self.unibox, '100%')
#             self.button.addClickListener(self.openRichMessageEditor)
#             self.unibox.addKey("@@: ")
#             self.unibox.onSelectedChange(self.host.getSelected())
#
#     def openRichMessageEditor(self):
#         """Open the rich text editor."""
#         self.button.setVisible(False)
#         self.unibox.setVisible(False)
#         self.setCellWidth(self.unibox, '0px')
#         self.host.panel._contactsMove(self)
#
#         def afterEditCb():
#             Window.removeWindowResizeListener(self)
#             self.host.panel._contactsMove(self.host.panel._hpanel)
#             self.setCellWidth(self.unibox, '100%')
#             self.button.setVisible(True)
#             self.unibox.setVisible(True)
#             self.host.resize()
#
#         richtext.RichMessageEditor.getOrCreate(self.host, self, afterEditCb)
#         Window.addWindowResizeListener(self)
#         self.host.resize()
#
#     def onWindowResized(self, width, height):
#         right = self.host.panel.menu.getAbsoluteLeft() + self.host.panel.menu.getOffsetWidth()
#         left = self.host.panel._contacts.getAbsoluteLeft() + self.host.panel._contacts.getOffsetWidth()
#         ideal_width = right - left - 40
#         self.host.richtext.setWidth("%spx" % ideal_width)



# class UniBox(MessageBox, MouseHandler):  # AutoCompleteTextBox):
#     """This text box is used as a main typing point, for message, microblog, etc"""
#
#     def __init__(self, host):
#         MessageBox.__init__(self, host)
#         #AutoCompleteTextBox.__init__(self)
#         self.setStyleName('uniBox')
#         # FIXME
#         # host.addSelectedListener(self.onSelectedChange)
#
#     def addKey(self, key):
#         return
#         #self.getCompletionItems().completions.append(key)
#
#     def removeKey(self, key):
#         return
#         # TODO: investigate why AutoCompleteTextBox doesn't work here,
#         # maybe it can work on a TextBox but no TextArea. Remove addKey
#         # and removeKey methods if they don't serve anymore.
#         try:
#             self.getCompletionItems().completions.remove(key)
#         except KeyError:
#             log.warning("trying to remove an unknown key")
#
#     def _getTarget(self, txt):
#         """ Say who will receive the messsage
#         @return: a tuple (selected, target_type, target info) with:
#             - 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))
#             - target_type: one of PUBLIC, GROUP, ONE2ONE, STATUS, MISC
#             - msg: HTML message which will appear in the privacy warning banner """
#         target = self._selected_cache
#
#         def getSelectedOrStatus():
#             if target and target.isSelectable():
#                 _type, msg = target.getWarningData()
#                 target_hook = None  # we use the selected widget, not a hook
#             else:
#                 _type, msg = "STATUS", "This will be your new status message"
#                 target_hook = (txt, None)
#             return (target_hook, _type, msg)
#
#         if not txt.startswith('@'):
#             target_hook, _type, msg = getSelectedOrStatus()
#         elif txt.startswith('@@: '):
#             _type = "PUBLIC"
#             msg = MicroblogPanel.warning_msg_public
#             target_hook = (txt[4:], None)
#         elif txt.startswith('@'):
#             _end = txt.find(': ')
#             if _end == -1:
#                 target_hook, _type, msg = getSelectedOrStatus()
#             else:
#                 group = txt[1:_end]  # only one target group is managed for the moment
#                 if not group or not group in self.host.contact_panel.getGroups():
#                     # the group doesn't exists, we ignore the key
#                     group = None
#                     target_hook, _type, msg = getSelectedOrStatus()
#                 else:
#                     _type = "GROUP"
#                     msg = MicroblogPanel.warning_msg_group % group
#                     target_hook = (txt[_end + 2:], group)
#         else:
#             log.error("Unknown target")
#             target_hook, _type, msg = getSelectedOrStatus()
#
#         return (target_hook, _type, msg)
#
#     def onKeyPress(self, sender, keycode, modifiers):
#         _txt = self.getText()
#         target_hook, type_, msg = self._getTarget(_txt)
#
#         if keycode == KEY_ENTER:
#             if _txt:
#                 if target_hook:
#                     parsed_txt, data = target_hook
#                     self.host.send([(type_, data)], parsed_txt)
#                     self.host._updateInputHistory(_txt)
#                     self.setText('')
#             self.host.showWarning(None, None)
#         else:
#             self.host.showWarning(type_, msg)
#         MessageBox.onKeyPress(self, sender, keycode, modifiers)
#
#     def getTargetAndData(self):
#         """For external use, to get information about the (hypothetical) message
#         that would be sent if we press Enter right now in the unibox.
#         @return a tuple (target, data) with:
#           - data: what would be the content of the message (body)
#           - target: JID, group with the prefix "@" or the public entity "@@"
#         """
#         _txt = self.getText()
#         target_hook, _type, _msg = self._getTarget(_txt)
#         if target_hook:
#             data, target = target_hook
#             if target is None:
#                 return target_hook
#             return (data, "@%s" % (target if target != "" else "@"))
#         if isinstance(self._selected_cache, MicroblogPanel):
#             groups = self._selected_cache.accepted_groups
#             target = "@%s" % (groups[0] if len(groups) > 0 else "@")
#             if len(groups) > 1:
#                 Window.alert("Sole the first group of the selected panel is taken in consideration: '%s'" % groups[0])
#         # elif isinstance(self._selected_cache, ChatPanel): # FIXME
#         #     target = self._selected_cache.target
#         else:
#             target = None
#         return (_txt, target)
#
#     def onWidgetClosed(self, lib_wid):
#         """Called when a libervia widget is closed"""
#         if self._selected_cache == lib_wid:
#             self.onSelectedChange(None)
#
#     """def complete(self):
#
#         #self.visible=False #XXX: self.visible is not unset in pyjamas when ENTER is pressed and a completion is done
#         #XXX: fixed directly on pyjamas, if the patch is accepted, no need to walk around this
#         return AutoCompleteTextBox.complete(self)"""


class WebWidget(quick_widgets.QuickWidget, libervia_widget.LiberviaWidget):
    """ (mini)browser like widget """

    def __init__(self, host, target, show_url=True, profiles=None):
        """
        @param host: SatWebFrontend instance
        @param target: url to open
        """
        quick_widgets.QuickWidget.__init__(self, host, target, C.PROF_KEY_NONE)
        libervia_widget.LiberviaWidget.__init__(self, host)
        self._vpanel = VerticalPanel()
        self._vpanel.setSize('100%', '100%')
        self._url = dialog.ExtTextBox(enter_cb=self.onUrlClick)
        self._url.setText(target or "")
        self._url.setWidth('100%')
        if show_url:
            hpanel = HorizontalPanel()
            hpanel.add(self._url)
            btn = Button("Go", self.onUrlClick)
            hpanel.setCellWidth(self._url, "100%")
            hpanel.add(btn)
            self._vpanel.add(hpanel)
            self._vpanel.setCellHeight(hpanel, '20px')
        self._frame = Frame(target or "")
        self._frame.setSize('100%', '100%')
        DOM.setStyleAttribute(self._frame.getElement(), "position", "relative")
        self._vpanel.add(self._frame)
        self.setWidget(self._vpanel)

    def onUrlClick(self, sender):
        url = self._url.getText()
        scheme_end = url.find(':')
        scheme = "" if scheme_end == -1 else url[:scheme_end]
        if scheme not in C.WEB_PANEL_SCHEMES:
            url = "http://" + url
        self._frame.setUrl(url)


##  Menu

def hostReady(host):
    def onWebWidget():
        web_widget = host.displayWidget(WebWidget, C.WEB_PANEL_DEFAULT_URL)
        host.setSelected(web_widget)

    def gotMenus():
        host.menus.addMenu(C.MENU_GLOBAL, (D_(u"General"), D_(u"Web widget")), callback=onWebWidget)
    host.addListener('gotMenus', gotMenus)

host_listener.addListener(hostReady)