Mercurial > libervia-desktop-kivy
view src/cagou/plugins/plugin_wid_chat.py @ 28:9f9532eb835f
core: added expand method to expand filename with magic values, specially useful in kv
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 21 Aug 2016 15:02:18 +0200 |
parents | d09bd16dbbe2 |
children | 20b04c58868f |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- # Cagou: desktop/mobile frontend for Salut à Toi XMPP client # Copyright (C) 2016 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/>. from sat.core import log as logging log = logging.getLogger(__name__) from sat.core.i18n import _ from cagou.core.constants import Const as C from kivy.uix.boxlayout import BoxLayout from kivy.uix.scrollview import ScrollView from kivy.uix.textinput import TextInput from kivy import properties from sat_frontends.quick_frontend import quick_widgets from sat_frontends.quick_frontend import quick_chat from sat_frontends.tools import jid from cagou.core import cagou_widget from cagou import G PLUGIN_INFO = { "name": _(u"chat"), "main": "Chat", "description": _(u"instant messaging with one person or a group"), "icon_small": u"{media}/icons/muchoslava/png/chat_rouge_32.png", "icon_medium": u"{media}/icons/muchoslava/png/chat_rouge_44.png" } class MessageWidget(BoxLayout): mess_data = properties.ObjectProperty() mess_label = properties.ObjectProperty(None) def __init__(self, **kwargs): BoxLayout.__init__(self, orientation='vertical', **kwargs) @property def message(self): """Return currently displayed message""" return self.mess_data.main_message def sizeAdjust(self): """this widget grows up with its children""" text_width, text_height = self.mess_label.texture_size if text_width > self.parent.width: self.mess_label.text_size = (self.parent.width - 10, None) self.text_max = text_width elif self.mess_label.text_size[0] is not None and text_width < self.parent.width - 10: if text_width > self.text_max: self.mess_label.text_size = (None, None) else: self.mess_label.text_size = (self.parent.width - 10, None) class MessageInputWidget(TextInput): def _key_down(self, key, repeat=False): displayed_str, internal_str, internal_action, scale = key if internal_action == 'enter': self.dispatch('on_text_validate') else: super(MessageInputWidget, self)._key_down(key, repeat) class MessagesWidget(BoxLayout): _spacing = properties.NumericProperty(10) _padding = properties.NumericProperty(5) def __init__(self, **kwargs): kwargs['orientation'] = 'vertical' kwargs['size_hint'] = (1, None) super(MessagesWidget, self).__init__(**kwargs) def sizeAdjust(self): self.height = sum([(c.height+self._padding*2) for c in self.children]) + self._spacing class Chat(quick_chat.QuickChat, cagou_widget.CagouWidget): def __init__(self, host, target, type_=C.CHAT_ONE2ONE, occupants=None, subject=None, profiles=None): quick_chat.QuickChat.__init__(self, host, target, type_, occupants, subject, profiles=profiles) cagou_widget.CagouWidget.__init__(self) self.header_input.hint_text = u"You are talking with {}".format(target) scroll_view = ScrollView(size_hint=(1,0.8), scroll_y=0) self.messages_widget = MessagesWidget() scroll_view.add_widget(self.messages_widget) self.add_widget(scroll_view) message_input = MessageInputWidget() message_input.bind(on_text_validate=self.onSend) self.add_widget(message_input) self.postInit() @classmethod def factory(cls, plugin_info, target, profiles): profiles = list(profiles) if len(profiles) > 1: raise NotImplementedError(u"Multi-profiles is not available yet for chat") if target is None: target = G.host.profiles[profiles[0]].whoami return G.host.widgets.getOrCreateWidget(cls, target, on_new_widget=None, on_existing_widget=C.WIDGET_RECREATE, profiles=profiles) def messageDataConverter(self, idx, mess_id): return {"mess_data": self.messages[mess_id]} def _onHistoryPrinted(self): """Refresh or scroll down the focus after the history is printed""" # self.adapter.data = self.messages for mess_data in self.messages.itervalues(): self.appendMessage(mess_data) super(Chat, self)._onHistoryPrinted() def createMessage(self, message): self.appendMessage(message) def appendMessage(self, mess_data): self.messages_widget.add_widget(MessageWidget(mess_data=mess_data)) def onSend(self, input_widget): G.host.messageSend( self.target, {'': input_widget.text}, # TODO: handle language mess_type = C.MESS_TYPE_GROUPCHAT if self.type == C.CHAT_GROUP else C.MESS_TYPE_CHAT, # TODO: put this in QuickChat profile_key=self.profile ) input_widget.text = '' def onHeaderInput(self): text = self.header_input.text.strip() try: if text.count(u'@') != 1 or text.count(u' '): raise ValueError jid_ = jid.JID(text) except ValueError: log.info(u"entered text is not a jid") return def discoCb(disco): # TODO: check if plugin XEP-0045 is activated if "conference" in [i[0] for i in disco[1]]: raise NotImplementedError(u"MUC not implemented yet") # G.host.bridge.MUCJoin(unicode(jid_), "", "", self.profile) else: plugin_info = [p for p in G.host.getPluggedWidgets() if p["factory"] == self.factory][0] # FIXME: Q&D way, need a proper method in host factory = plugin_info['factory'] G.host.switchWidget(self, factory(plugin_info, jid_, profiles=[self.profile])) def discoEb(failure): log.warning(u"Disco failure, ignore this text: {}".format(failure)) G.host.bridge.discoInfos(jid_.domain, self.profile, callback=discoCb, errback=discoEb) PLUGIN_INFO["factory"] = Chat.factory quick_widgets.register(quick_chat.QuickChat, Chat)