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

View File

@@ -13,8 +13,8 @@
"win32" "win32"
], ],
"requirements": [ "requirements": [
"gajim>=1.4.0" "gajim>=1.5.0"
], ],
"short_name": "length_notifier", "short_name": "length_notifier",
"version": "1.4.5" "version": "1.4.6"
} }