Mercurial > libervia-web
view browser_side/menu.py @ 444:b64e528fb524
server side: use of bridge's getReady to be sure that backend is initialised at launch
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 15 May 2014 20:27:52 +0200 |
parents | d52f529a6d42 |
children |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- # Libervia: a Salut à Toi frontend # Copyright (C) 2011, 2012, 2013, 2014 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 pyjamas.ui.SimplePanel import SimplePanel from pyjamas.ui.MenuBar import MenuBar from pyjamas.ui.MenuItem import MenuItem from pyjamas.ui.HTML import HTML from pyjamas.ui.Frame import Frame from pyjamas import Window from jid import JID from file_tools import FileUploadPanel from xmlui import XMLUI from browser_side import panels from browser_side import dialog from contact_group import ContactGroupEditor from sat.core.i18n import _ class MenuCmd: def __init__(self, object_, handler): self._object = object_ self._handler = handler def execute(self): handler = getattr(self._object, self._handler) handler() class PluginMenuCmd: def __init__(self, host, action_id): self.host = host self.action_id = action_id def execute(self): self.host.launchAction(self.action_id, None) class LiberviaMenuBar(MenuBar): def __init__(self): MenuBar.__init__(self, vertical=False) self.setStyleName('gwt-MenuBar-horizontal') # XXX: workaround for the Pyjamas' class name fix (it's now "gwt-MenuBar gwt-MenuBar-horizontal") # TODO: properly adapt CSS to the new class name def doItemAction(self, item, fireCommand): MenuBar.doItemAction(self, item, fireCommand) if item == self.items[-1] and self.popup: self.popup.setPopupPosition(Window.getClientWidth() - self.popup.getOffsetWidth() - 22, self.getAbsoluteTop() + self.getOffsetHeight() - 1) self.popup.addStyleName('menuLastPopup') class AvatarUpload(FileUploadPanel): def __init__(self): texts = {'ok_button': 'Upload avatar', 'body': 'Please select an image to show as your avatar...<br>Your picture must be a square and will be resized to 64x64 pixels if necessary.', 'errback': "Can't open image... did you actually submit an image?", 'body_errback': 'Please select another image file.', 'callback': "Your new profile picture has been set!"} FileUploadPanel.__init__(self, 'upload_avatar', 'avatar_path', 2, texts) class Menu(SimplePanel): def __init__(self, host): self.host = host SimplePanel.__init__(self) self.setStyleName('menuContainer') def createMenus(self, add_menus): _item_tpl = "<img src='media/icons/menu/%s_menu_red.png' />%s" menus_dict = {} menus_order = [] def addMenu(menu_name, menu_name_i18n, item_name_i18n, icon, menu_cmd): """ add a menu to menu_dict """ log.info("addMenu: %s %s %s %s %s" % (menu_name, menu_name_i18n, item_name_i18n, icon, menu_cmd)) try: menu_bar = menus_dict[menu_name] except KeyError: menu_bar = menus_dict[menu_name] = MenuBar(vertical=True) menus_order.append((menu_name, menu_name_i18n, icon)) if item_name_i18n and menu_cmd: menu_bar.addItem(item_name_i18n, menu_cmd) addMenu("General", _("General"), _("Web widget"), 'home', MenuCmd(self, "onWebWidget")) addMenu("General", _("General"), _("Disconnect"), 'home', MenuCmd(self, "onDisconnect")) addMenu("Contacts", _("Contacts"), None, 'social', None) addMenu("Groups", _("Groups"), _("Discussion"), 'social', MenuCmd(self, "onJoinRoom")) addMenu("Groups", _("Groups"), _("Collective radio"), 'social', MenuCmd(self, "onCollectiveRadio")) addMenu("Games", _("Games"), _("Tarot"), 'games', MenuCmd(self, "onTarotGame")) addMenu("Games", _("Games"), _("Xiangqi"), 'games', MenuCmd(self, "onXiangqiGame")) # additional menus for action_id, type_, path, path_i18n in add_menus: if not path: log.warning("skipping menu without path") continue if len(path) != len(path_i18n): log.error("inconsistency between menu paths") continue menu_name = path[0] menu_name_i18n = path_i18n[0] item_name = path[1:] if not item_name: log.warning("skipping menu with a path of lenght 1 [%s]" % path[0]) continue item_name_i18n = ' | '.join(path_i18n[1:]) addMenu(menu_name, menu_name_i18n, item_name_i18n, 'plugins', PluginMenuCmd(self.host, action_id)) # menu items that should be displayed after the automatically added ones addMenu("Contacts", _("Contacts"), _("Manage groups"), 'social', MenuCmd(self, "onManageContactGroups")) menus_order.append(None) # we add separator addMenu("Help", _("Help"), _("Social contract"), 'help', MenuCmd(self, "onSocialContract")) addMenu("Help", _("Help"), _("About"), 'help', MenuCmd(self, "onAbout")) addMenu("Settings", _("Settings"), _("Account"), 'settings', MenuCmd(self, "onAccount")) addMenu("Settings", _("Settings"), _("Parameters"), 'settings', MenuCmd(self, "onParameters")) # XXX: temporary, will change when a full profile will be managed in SàT addMenu("Settings", _("Settings"), _("Upload avatar"), 'settings', MenuCmd(self, "onAvatarUpload")) menubar = LiberviaMenuBar() for menu_data in menus_order: if menu_data is None: _separator = MenuItem('', None) _separator.setStyleName('menuSeparator') menubar.addItem(_separator, None) else: menu_name, menu_name_i18n, icon = menu_data menubar.addItem(MenuItem(_item_tpl % (icon, menu_name_i18n), True, menus_dict[menu_name])) self.add(menubar) #General menu def onWebWidget(self): web_panel = panels.WebPanel(self.host, "http://www.goffi.org") self.host.addWidget(web_panel) self.host.setSelected(web_panel) def onDisconnect(self): def confirm_cb(answer): if answer: log.info("disconnection") self.host.bridge.call('disconnect', None) _dialog = dialog.ConfirmDialog(confirm_cb, text="Do you really want to disconnect ?") _dialog.show() def onSocialContract(self): _frame = Frame('contrat_social.html') _frame.setStyleName('infoFrame') _dialog = dialog.GenericDialog("Contrat Social", _frame) _dialog.setSize('80%', '80%') _dialog.show() def onAbout(self): _about = HTML("""<b>Libervia</b>, a Salut à Toi project<br /> <br /> You can contact the author at <a href="mailto:goffi@goffi.org">goffi@goffi.org</a><br /> Blog available (mainly in french) at <a href="http://www.goffi.org" target="_blank">http://www.goffi.org</a><br /> Project page: <a href="http://sat.goffi.org"target="_blank">http://sat.goffi.org</a><br /> <br /> Any help welcome :) <p style='font-size:small;text-align:center'>This project is dedicated to Roger Poisson</p> """) _dialog = dialog.GenericDialog("About", _about) _dialog.show() #Contact menu def onManageContactGroups(self): """Open the contact groups manager.""" def onCloseCallback(): pass ContactGroupEditor(self.host, None, onCloseCallback) #Group menu def onJoinRoom(self): def invite(room_jid, contacts): for contact in contacts: self.host.bridge.call('inviteMUC', None, contact, room_jid) def join(room_jid, contacts): if self.host.whoami: nick = self.host.whoami.node if room_jid not in [room.bare for room in self.host.room_list]: self.host.bridge.call('joinMUC', lambda room_jid: invite(room_jid, contacts), room_jid, nick) else: self.host.getOrCreateLiberviaWidget(panels.ChatPanel, (room_jid, "group"), True, JID(room_jid).bare) invite(room_jid, contacts) dialog.RoomAndContactsChooser(self.host, join, ok_button="Join", visible=(True, False)) def onCollectiveRadio(self): def callback(room_jid, contacts): self.host.bridge.call('launchRadioCollective', None, contacts, room_jid) dialog.RoomAndContactsChooser(self.host, callback, ok_button="Choose", title="Collective Radio", visible=(False, True)) #Game menu def onTarotGame(self): def onPlayersSelected(room_jid, other_players): self.host.bridge.call('launchTarotGame', None, other_players, room_jid) dialog.RoomAndContactsChooser(self.host, onPlayersSelected, 3, title="Tarot", title_invite="Please select 3 other players", visible=(False, True)) def onXiangqiGame(self): Window.alert("A Xiangqi game is planed, but not available yet") #Settings menu def onAccount(self): def gotUI(xmlui): if not xmlui: return body = XMLUI(self.host, xmlui) _dialog = dialog.GenericDialog("Manage your XMPP account", body, options=['NO_CLOSE']) body.setCloseCb(_dialog.close) _dialog.show() self.host.bridge.call('getAccountDialogUI', gotUI) def onParameters(self): def gotParams(xmlui): if not xmlui: return body = XMLUI(self.host, xmlui) _dialog = dialog.GenericDialog("Parameters", body, options=['NO_CLOSE']) body.setCloseCb(_dialog.close) _dialog.setSize('80%', '80%') _dialog.show() self.host.bridge.call('getParamsUI', gotParams) def removeItemParams(self): """Remove the Parameters item from the Settings menu bar.""" self.menu_settings.removeItem(self.item_params) def onAvatarUpload(self): body = AvatarUpload() _dialog = dialog.GenericDialog("Avatar upload", body, options=['NO_CLOSE']) body.setCloseCb(_dialog.close) _dialog.setWidth('40%') _dialog.show()