view cagou/core/common_widgets.py @ 391:841045d5a937

common: when possible, a more user friendly name is displayed for the contact, instead of the jid.
author Goffi <goffi@goffi.org>
date Thu, 06 Feb 2020 21:16:21 +0100
parents 1da3c379205b
children f7476818f9fb
line wrap: on
line source

#!/usr/bin/env python3


# Cagou: desktop/mobile frontend for Salut à Toi XMPP client
# Copyright (C) 2016-2020 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/>.

"""common advanced widgets, which can be reused everywhere."""

from sat.core.i18n import _
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from cagou.core.menu import TouchMenuItemBehaviour
from kivy import properties
from kivy.metrics import dp
from kivy.clock import Clock
from cagou import G
from sat.core import log as logging

log = logging.getLogger(__name__)


class DelayedBoxLayout(BoxLayout):
    """A BoxLayout with delayed layout, to avoid slowing down during resize"""
    # XXX: thanks to Alexander Taylor for his blog post at
    #      https://blog.kivy.org/2019/07/a-delayed-resize-layout-in-kivy/

    do_layout_event = properties.ObjectProperty(None, allownone=True)
    layout_delay_s = properties.NumericProperty(0.2)
    #: set this to X to force next X layouts to be done without delay
    dont_delay_next_layouts = properties.NumericProperty(0)

    def do_layout(self, *args, **kwargs):
        if self.do_layout_event is not None:
            self.do_layout_event.cancel()
        if self.dont_delay_next_layouts>0:
            self.dont_delay_next_layouts-=1
            super().do_layout()
        else:
            real_do_layout = super().do_layout
            self.do_layout_event = Clock.schedule_once(
                lambda dt: real_do_layout(*args, **kwargs),
                self.layout_delay_s)


class Identities(object):

    def __init__(self, entity_ids):
        identities = {}
        for cat, type_, name in entity_ids:
            identities.setdefault(cat, {}).setdefault(type_, []).append(name)
        client = identities.get('client', {})
        if 'pc' in client:
            self.type = 'desktop'
        elif 'phone' in client:
            self.type = 'phone'
        elif 'web' in client:
            self.type = 'web'
        elif 'console' in client:
            self.type = 'console'
        else:
            self.type = 'desktop'

        self.identities = identities

    @property
    def name(self):
        first_identity = next(iter(self.identities.values()))
        names = next(iter(first_identity.values()))
        return names[0]


class ItemWidget(TouchMenuItemBehaviour, BoxLayout):
    name = properties.StringProperty()
    base_width = properties.NumericProperty(dp(100))


class DeviceWidget(ItemWidget):

    def __init__(self, main_wid, entity_jid, identities, **kw):
        self.entity_jid = entity_jid
        self.identities = identities
        own_jid = next(iter(G.host.profiles.values())).whoami
        self.own_device = entity_jid.bare == own_jid.bare
        if self.own_device:
            name = self.identities.name
        elif self.entity_jid.node:
            name = self.entity_jid.node
        elif self.entity_jid == own_jid.domain:
            name = _("your server")
        else:
            name = entity_jid

        super(DeviceWidget, self).__init__(name=name, main_wid=main_wid, **kw)

    @property
    def profile(self):
        return self.main_wid.profile

    def getSymbol(self):
        if self.identities.type == 'desktop':
            return 'desktop'
        elif self.identities.type == 'phone':
            return 'mobile'
        elif self.identities.type == 'web':
            return 'globe'
        elif self.identities.type == 'console':
            return 'terminal'
        else:
            return 'desktop'

    def do_item_action(self, touch):
        pass


class CategorySeparator(Label):
    pass