[length_notifier] 1.4.6

This commit is contained in:
wurstsalat
2022-08-16 09:35:34 +02:00
committed by Philipp Hörist
parent 4003411ae5
commit c400a7f2fc
2 changed files with 140 additions and 72 deletions

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# This file is part of Gajim.
#
# Gajim is free software; you can redistribute it and/or modify
@@ -23,17 +21,27 @@ Message length notifier plugin.
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
:license: GPL
'''
from __future__ import annotations
from typing import Any, cast
import logging
from functools import partial
from gi.repository import Gdk
from gi.repository import GObject
from gi.repository import Gtk
from nbxmpp.protocol import JID
from gajim.common import app
from gajim.common import types
from gajim.gui.message_actions_box import MessageActionsBox
from gajim.gui.message_input import MessageInputTextView
from gajim.plugins import GajimPlugin
from gajim.plugins.gajimplugin import GajimPluginConfig
from gajim.plugins.plugins_i18n import _
from length_notifier.config_dialog import LengthNotifierConfigDialog
@@ -42,17 +50,15 @@ log = logging.getLogger('gajim.p.length_notifier')
class LengthNotifierPlugin(GajimPlugin):
def init(self):
def init(self) -> None:
self.description = _('Highlights the chat windows message input if '
'a specified message length is exceeded.')
self.config_dialog = partial(LengthNotifierConfigDialog, self)
self.gui_extension_points = {
'chat_control_base': (
self._connect_chat_control,
self._disconnect_chat_control
)
'message_actions_box': (self._connect, None),
'switch_contact': (self._on_switch_contact, None)
}
self.config_default_values = {
@@ -63,66 +69,95 @@ class LengthNotifierPlugin(GajimPlugin):
'rgb(240, 220, 60)',
'Highlight color for the message input'),
'JIDS': (
[],
[''],
'Enable the plugin for selected XMPP addresses '
'only (comma separated)')
}
self._counters = {}
self._message_action_box = None
self._actions_box_widget = None
self._counter = None
self._contact = None
def _connect_chat_control(self, chat_control):
jid = chat_control.contact.jid
if self._check_jid(jid):
counter = Counter(chat_control, self.config)
self._counters[chat_control.control_id] = counter
actions_hbox = chat_control.xml.get_object('hbox')
actions_hbox.pack_start(counter, False, False, 0)
counter.show()
def activate(self) -> None:
if self._counter is not None and self._contact is not None:
self._counter.update_contact(self._contact)
def _disconnect_chat_control(self, chat_control):
counter = self._counters.get(chat_control.control_id)
if counter is not None:
counter.reset()
counter.destroy()
self._counters.pop(chat_control.control_id, None)
def deactivate(self) -> None:
assert self._counter is not None
self._counter.destroy()
del self._counter
def _check_jid(self, jid):
if not self.config['JIDS']:
# Not restricted to any JIDs
return True
def _create_counter(self) -> None:
assert self._message_action_box is not None
assert self._actions_box_widget is not None
self._counter = Counter(self._message_action_box.msg_textview,
self.config)
self._actions_box_widget.pack_end(self._counter, False, False, 0)
current_jid = JID.from_string(jid)
allowed_jids = self.config['JIDS'].split(',')
for allowed_jid in allowed_jids:
try:
address = JID.from_string(allowed_jid.strip())
except Exception as error:
log.debug('Error parsing JID: %s (%s)' % (error, allowed_jid))
continue
if address.is_domain:
if current_jid.domain == address:
log.debug('Add counter for Domain %s' % address)
return True
if current_jid == address:
log.debug('Add counter for JID %s' % address)
return True
def _connect(self,
message_actions_box: MessageActionsBox,
gtk_box: Gtk.Box
) -> None:
self._message_action_box = message_actions_box
self._actions_box_widget = gtk_box
self._create_counter()
def _on_switch_contact(self, contact: types.ChatContactT) -> None:
if self._counter is None:
return
self._contact = contact
self._counter.update_contact(contact)
def update(self):
if not app.plugin_manager.get_active_plugin('length_notifier'):
# Dont update if the plugin is disabled
return
for control in app.window.get_controls():
self._disconnect_chat_control(control)
self._connect_chat_control(control)
assert self._counter is not None
if self._contact is not None:
self._counter.update_config(self.config)
class Counter(Gtk.Label):
def __init__(self, chat_control, config):
Gtk.Label.__init__(self)
self._control = chat_control
self._max_length = config['MESSAGE_WARNING_LENGTH']
self._color = config['WARNING_COLOR']
def __init__(self,
message_input: MessageInputTextView,
config: GajimPluginConfig
) -> None:
Gtk.Label.__init__(self)
self.set_tooltip_text(_('Number of typed characters'))
self.get_style_context().add_class('dim-label')
self._config = config
self._contact = None
self._max_length = None
self._color = None
self._inverted_color = None
self._textview = message_input
self._textbuffer = self._textview.get_buffer()
self._signal_id = self._textbuffer.connect('changed', self._update)
self._provider = None
self._parse_config()
self._set_css()
self.connect('destroy', self._on_destroy)
def _on_destroy(self, _widget: Counter) -> None:
self._context.remove_class('length-warning')
assert self._textbuffer is not None
assert self._signal_id is not None
if GObject.signal_handler_is_connected(
self._textbuffer, self._signal_id):
self._textbuffer.disconnect(self._signal_id)
app.check_finalize(self)
def _parse_config(self) -> None:
self._max_length = cast(int, self._config['MESSAGE_WARNING_LENGTH'])
self._color = cast(str, self._config['WARNING_COLOR'])
rgba = Gdk.RGBA()
rgba.parse(self._color)
red = int(255 - rgba.red * 255)
@@ -130,18 +165,7 @@ class Counter(Gtk.Label):
blue = int(255 - rgba.blue * 255)
self._inverted_color = f'rgb({red}, {green}, {blue})'
self.set_tooltip_text(_('Number of typed characters'))
self.get_style_context().add_class('dim-label')
self._textview = self._control.msg_textview
self._textbuffer = self._textview.get_buffer()
self._textbuffer.connect('changed', self._update)
self._provider = None
self._set_css()
self._update()
def _set_css(self):
def _set_css(self) -> None:
self._context = self._textview.get_style_context()
if self._provider is not None:
self._context.remove_provider(self._provider)
@@ -156,11 +180,21 @@ class Counter(Gtk.Label):
self._context.add_provider(
self._provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
def _set_count(self, count):
def _set_count(self, count: int) -> None:
self.set_label(str(count))
def _update(self, *args):
if self._textview.has_text():
def _update(self, *args: Any) -> bool:
if self._contact is None:
return False
enable = self._jid_allowed(self._contact.jid)
if enable:
self.show()
else:
self.hide()
assert self._max_length is not None
if self._textview.has_text and enable:
text = self._textbuffer.get_text(
self._textbuffer.get_start_iter(),
self._textbuffer.get_end_iter(),
@@ -172,8 +206,42 @@ class Counter(Gtk.Label):
else:
self._context.remove_class('length-warning')
else:
self._set_count('0')
self._set_count(0)
self._context.remove_class('length-warning')
return False
def reset(self):
def _jid_allowed(self, current_jid: JID) -> bool:
jids = cast(str, self._config['JIDS'])
if not len(jids):
# Not restricted to any JIDs
return True
allowed_jids = jids.split(',')
for allowed_jid in allowed_jids:
try:
address = JID.from_string(allowed_jid.strip())
except Exception as error:
log.error('Error parsing JID: %s (%s)' % (error, allowed_jid))
continue
if address.is_domain:
if current_jid.domain == address:
log.debug('Show counter for Domain %s' % address)
return True
if current_jid == address:
log.debug('Show counter for JID %s' % address)
return True
return False
def update_config(self, config: GajimPluginConfig) -> None:
self._config = config
self.reset()
self._update()
def update_contact(self, contact: types.ChatContactT) -> None:
self._contact = contact
self._update()
def reset(self) -> None:
self._context.remove_class('length-warning')
self._parse_config()
self._set_css()