chatstate.py 3.92 KB
Newer Older
Dicson's avatar
Dicson committed
1 2 3
# -*- coding: utf-8 -*-
##

Dicson's avatar
Dicson committed
4
from gi.repository import GObject
Dicson's avatar
Dicson committed
5

6 7 8 9 10 11
from gajim.plugins import GajimPlugin
from gajim.plugins.helpers import log_calls
from gajim.common import ged
from gajim.common import app
from gajim.common import helpers
from gajim import gtkgui_helpers
Dicson's avatar
Dicson committed
12
import unicodedata
Dicson's avatar
Dicson committed
13

Dicson's avatar
Dicson committed
14 15 16 17 18 19 20 21 22 23
def paragraph_direction_mark(text):
    """
    Determine paragraph writing direction according to
    http://www.unicode.org/reports/tr9/#The_Paragraph_Level

    Returns either Unicode LTR mark or RTL mark.
    """
    for char in text:
        bidi = unicodedata.bidirectional(char)
        if bidi == 'L':
Dicson's avatar
Dicson committed
24
            return '\u200E'
Dicson's avatar
Dicson committed
25
        elif bidi == 'AL' or bidi == 'R':
Dicson's avatar
Dicson committed
26
            return '\u200F'
Dicson's avatar
Dicson committed
27

Dicson's avatar
Dicson committed
28
    return '\u200E'
Dicson's avatar
Dicson committed
29 30 31 32 33

class ChatstatePlugin(GajimPlugin):

    @log_calls('ChatstatePlugin')
    def init(self):
Dicson's avatar
Dicson committed
34 35 36 37
        self.description = _('Chat State Notifications in roster.'
'Font color of the contact varies depending on the chat state.\n'
'The plugin does not work if you use custom font color for contacts in roster.\n'
'http://trac.gajim.org/ticket/3628.\nhttp://xmpp.org/extensions/xep-0085.html')
Dicson's avatar
Dicson committed
38
        self.config_dialog = None  # ChatstatePluginConfigDialog(self)
Dicson's avatar
Dicson committed
39 40
        self.events_handlers = {'chatstate-received':
                                    (ged.GUI2, self.chatstate_received), }
41
        self.active = None
Dicson's avatar
Dicson committed
42

Dicson's avatar
Dicson committed
43
    def chatstate_received(self, obj):
44 45
        if not self.active:
            return
Dicson's avatar
Dicson committed
46

47
        contact = app.contacts.get_contact_from_full_jid(obj.conn.name,
Dicson's avatar
Dicson committed
48
            obj.fjid)
Dicson's avatar
Dicson committed
49 50 51
        if not contact:
            return

Dicson's avatar
Dicson committed
52
        chatstate = obj.chatstate
53
        if chatstate not in self.chatstates.keys():
Dicson's avatar
Dicson committed
54 55
            return

56 57
        self.model = app.interface.roster.model
        child_iters = app.interface.roster._get_contact_iter(obj.jid,
Dicson's avatar
Dicson committed
58
            obj.conn.name, contact, self.model)
Dicson's avatar
Dicson committed
59

Dicson's avatar
Dicson committed
60
        name = GObject.markup_escape_text(contact.get_shown_name())
61
        contact_instances = app.contacts.get_contacts(obj.conn.name,
Dicson's avatar
Dicson committed
62 63 64 65 66 67 68 69
            contact.jid)

        # Show resource counter
        nb_connected_contact = 0
        for c in contact_instances:
            if c.show not in ('error', 'offline'):
                nb_connected_contact += 1
        if nb_connected_contact > 1:
Dicson's avatar
Dicson committed
70
            name += paragraph_direction_mark(name)
Dicson's avatar
Dicson committed
71
            name += ' (%d)' % nb_connected_contact
Dicson's avatar
Dicson committed
72

Dicson's avatar
Dicson committed
73
        for child_iter in child_iters:
74
            if chatstate != 'gone':
75 76
                color = self.chatstates[chatstate]
                name = '<span foreground="%s">%s</span>' % (color, name)
77
            if contact.status and app.config.get(
Dicson's avatar
Dicson committed
78
            'show_status_msgs_in_roster'):
Dicson's avatar
Dicson committed
79 80 81
                status = contact.status.strip()
                if status != '':
                    status = helpers.reduce_chars_newlines(status,
Dicson's avatar
Dicson committed
82
                            max_lines=1)
Dicson's avatar
Dicson committed
83
                    name += '\n<span size="small" style="italic" ' \
84
                            'foreground="%s">%s</span>' % (self.status_color,
Dicson's avatar
Dicson committed
85
                            GObject.markup_escape_text(status))
Dicson's avatar
Dicson committed
86 87 88 89
            self.model[child_iter][1] = name

    @log_calls('ChatstatePlugin')
    def activate(self):
90
        color = gtkgui_helpers.get_fade_color(app.interface.roster.tree,
91 92 93
            False, False)
        self.status_color = '#%04x%04x%04x' % (color.red, color.green,
            color.blue)
94 95 96
        theme = app.config.get('roster_theme')
        self.chatstates = {'active': app.config.get('inmsgcolor'),
                            'composing': app.config.get_per('themes', theme,
97
                                         'state_composing_color'),
98
                            'inactive': app.config.get_per('themes', theme,
99
                                        'state_inactive_color'),
100
                            'paused': app.config.get_per('themes', theme,
101 102
                                        'state_paused_color'),
                            'gone': None, }
103
        self.active = True
Dicson's avatar
Dicson committed
104 105 106

    @log_calls('ChatstatePlugin')
    def deactivate(self):
107
        self.active = False