From 452ec6973550947a0e4ca55bb2df92f898c315d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Br=C3=B6tzmann?= Date: Sun, 19 Jan 2020 00:20:50 +0100 Subject: [PATCH] [length_notifier] Rework plugin --- length_notifier/config_dialog.py | 80 +++++++++ length_notifier/config_dialog.ui | 111 ------------ length_notifier/length_notifier.py | 274 ++++++++++++----------------- 3 files changed, 196 insertions(+), 269 deletions(-) create mode 100644 length_notifier/config_dialog.py delete mode 100644 length_notifier/config_dialog.ui diff --git a/length_notifier/config_dialog.py b/length_notifier/config_dialog.py new file mode 100644 index 0000000..f6a8b2d --- /dev/null +++ b/length_notifier/config_dialog.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Gajim. +# +# Gajim is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Gajim 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see . + +from gi.repository import GObject +from gi.repository import Gtk + +from gajim.gtk.settings import SettingsDialog +from gajim.gtk.settings import SpinSetting +from gajim.gtk.const import Setting +from gajim.gtk.const import SettingKind +from gajim.gtk.const import SettingType + +from gajim.plugins.plugins_i18n import _ + + +class LengthNotifierConfigDialog(SettingsDialog): + def __init__(self, plugin, parent): + self.plugin = plugin + settings = [ + Setting('MessageLengthSpinSetting', + _('Message Length'), + SettingType.VALUE, + self.plugin.config['MESSAGE_WARNING_LENGTH'], + callback=self._on_setting, + data='MESSAGE_WARNING_LENGTH', + desc=_('Message length at which the highlight is shown'), + props={'range_': (1, 1000)}, + ), + Setting(SettingKind.COLOR, + _('Color'), + SettingType.VALUE, + self.plugin.config['WARNING_COLOR'], + callback=self._on_setting, + data='WARNING_COLOR', + desc=_('Highlight color for the message input'), + ), + Setting(SettingKind.ENTRY, + _('Selected Addresses'), + SettingType.VALUE, + self.plugin.config['JIDS'], + callback=self._on_setting, + data='JIDS', + desc=_('Enable the plugin for selected XMPP addresses ' + 'only (comma separated)'), + ), + ] + + SettingsDialog.__init__(self, parent, + _('Length Notifier Configuration'), + Gtk.DialogFlags.MODAL, settings, None, + extend=[('MessageLengthSpinSetting', + SizeSpinSetting)]) + + def _on_setting(self, value, data): + self.plugin.config[data] = value + self.plugin.update_settings() + + +class SizeSpinSetting(SpinSetting): + + __gproperties__ = { + "setting-value": (int, 'Size', '', 1, 1000, 140, + GObject.ParamFlags.READWRITE), } + + def __init__(self, *args, **kwargs): + SpinSetting.__init__(self, *args, **kwargs) diff --git a/length_notifier/config_dialog.ui b/length_notifier/config_dialog.ui deleted file mode 100644 index cca3ff1..0000000 --- a/length_notifier/config_dialog.ui +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - False - - - - - - True - False - Background color of the text entry when the specified message length is exceeded - center - 18 - 6 - 12 - - - True - False - end - Message Length - - - - 0 - 0 - - - - - True - True - Message length for the notification to be shown (set to 0 to disable color notification) - start - 6 - number - True - True - - - - 1 - 0 - - - - - True - False - end - Notification Color - - - - 0 - 1 - - - - - True - True - True - Background color of the message input when the specified message length is reached - start - Pick a color for notification - - - 1 - 1 - - - - - True - False - end - XMPP Addresses - - - - 0 - 2 - - - - - True - True - Restrict this plugin to certain contacts, e.g. to one microblogging bot (use comma without space as separator) - start - user@example.org - - - 1 - 2 - - - - - - diff --git a/length_notifier/length_notifier.py b/length_notifier/length_notifier.py index 5c1dab3..a68b2b8 100644 --- a/length_notifier/length_notifier.py +++ b/length_notifier/length_notifier.py @@ -1,19 +1,19 @@ # -*- coding: utf-8 -*- -## This file is part of Gajim. -## -## Gajim is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published -## by the Free Software Foundation; version 3 only. -## -## Gajim 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 General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Gajim. If not, see . -## +# This file is part of Gajim. +# +# Gajim is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# Gajim 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see . +# ''' Message length notifier plugin. @@ -23,173 +23,131 @@ Message length notifier plugin. :copyright: Copyright (2008) Mateusz Biliński :license: GPL ''' +import logging +from functools import partial from gi.repository import Gtk -from gi.repository import Gdk from gajim.plugins import GajimPlugin -from gajim.plugins.helpers import log_calls -from gajim.plugins.gui import GajimPluginConfigDialog from gajim.plugins.plugins_i18n import _ +from length_notifier.config_dialog import LengthNotifierConfigDialog + +log = logging.getLogger('gajim.p.length_notifier') + class LengthNotifierPlugin(GajimPlugin): - - @log_calls('LengthNotifierPlugin') def init(self): - self.description = _('Highlights message entry field in chat window ' - 'when given length of message is exceeded.') - self.config_dialog = LengthNotifierPluginConfigDialog(self) + self.description = _('Highlights the chat window’s message input if ' + 'a specified message length is exceeded.') + + self.config_dialog = partial(LengthNotifierConfigDialog, self) self.gui_extension_points = { 'chat_control_base': ( - self.connect_with_chat_control, - self.disconnect_from_chat_control) + self._on_connect_chat_control, + self._on_disconnect_chat_control + ) } self.config_default_values = { - 'MESSAGE_WARNING_LENGTH' : (140, 'Message length at which notification is invoked.'), - 'WARNING_COLOR' : ('#F0DB3E', 'Background color of text entry field in chat window when notification is invoked.'), - 'JIDS' : ([], 'JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]') + 'MESSAGE_WARNING_LENGTH': ( + 140, + 'Message length at which the highlight is shown'), + 'WARNING_COLOR': ( + 'rgb(240, 220, 60)', + 'Highlight color for the message input'), + 'JIDS': ( + [], + 'Enable the plugin for selected XMPP addresses ' + 'only (comma separated)') } - @log_calls('LengthNotifierPlugin') - def textview_length_warning(self, tb, chat_control): - tv = chat_control.msg_textview - d = chat_control.length_notifier_plugin_data - counter = d['counter'] - if not tv.has_text(): - counter.set_text('0') - if tv.has_text(): - t = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True) - len_t = len(t) - counter.set_text(str(len_t)) - warning_length = self.config['MESSAGE_WARNING_LENGTH'] - if len_t > warning_length and warning_length != 0: - if not d['prev_color']: - #FIXME: That doesn't work - context = tv.get_style_context() - d['prev_color'] = context.get_background_color( - Gtk.StateFlags.NORMAL) - color = Gdk.RGBA() - Gdk.RGBA.parse(color, self.config['WARNING_COLOR']) - tv.override_background_color(Gtk.StateFlags.NORMAL, color) - elif d['prev_color']: - tv.override_background_color(Gtk.StateFlags.NORMAL, - d['prev_color']) - d['prev_color'] = None - elif d['prev_color']: - tv.override_background_color(Gtk.StateFlags.NORMAL, d['prev_color']) - d['prev_color'] = None + self._counters = {} - @log_calls('LengthNotifierPlugin') - def connect_with_chat_control(self, chat_control): + def _on_connect_chat_control(self, chat_control): jid = chat_control.contact.jid - if self.jid_is_ok(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') - counter = Gtk.Label() - counter.set_tooltip_text(_('Number of typed characters')) - counter.get_style_context().add_class('dim-label') - counter.show() actions_hbox.pack_start(counter, False, False, 0) + counter.show() - d = {'prev_color' : None} - tv = chat_control.msg_textview - tb = tv.get_buffer() - h_id = tb.connect('changed', self.textview_length_warning, - chat_control) - d['h_id'] = h_id - d['counter'] = counter + def _on_disconnect_chat_control(self, chat_control): + counter = self._counters.get(chat_control.control_id) + if counter is not None: + counter.destroy() + self._counters.pop(chat_control.control_id, None) - if tv.has_text(): - t = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True) - len_t = len(t) - counter.set_text(str(len_t)) - warning_length = self.config['MESSAGE_WARNING_LENGTH'] - if len_t > warning_length and warning_length != 0: - context = tv.get_style_context() - d['prev_color'] = context.get_background_color( - Gtk.StateFlags.NORMAL) - color = Gdk.RGBA() - Gdk.RGBA.parse(color, self.config['WARNING_COLOR']) - tv.override_background_color(Gtk.StateType.NORMAL, color) + def _check_jid(self, jid): + allowed_jids = [] + if len(self.config['JIDS']) > 0: + allowed_jids = self.config['JIDS'].split(',') + + jid_allowed = jid in allowed_jids or not self.config['JIDS'] + if not jid_allowed: + log.debug('No counter for JID %s' % jid) + return jid_allowed + + def update_settings(self): + for counter in self._counters.values(): + counter.update_settings(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'] + + 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._text_changed) + self._provider = None + + self._set_count('0') + self._set_css() + + def _set_css(self): + self._context = self._textview.get_style_context() + if self._provider is not None: + self._context.remove_provider(self._provider) + css = ''' + .length-warning > * { + background-color: %s; + } + ''' % self._color + self._provider = Gtk.CssProvider() + self._provider.load_from_data(bytes(css.encode())) + self._context.add_provider( + self._provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) + + def _text_changed(self, *args): + if self._textview.has_text(): + text = self._textbuffer.get_text( + self._textbuffer.get_start_iter(), + self._textbuffer.get_end_iter(), + True) + len_text = len(text) + self._set_count(len_text) + if len_text > self._max_length: + self._context.add_class('length-warning') else: - counter.set_text('0') - chat_control.length_notifier_plugin_data = d - - return True - - return False - - @log_calls('LengthNotifierPlugin') - def disconnect_from_chat_control(self, chat_control): - try: - d = chat_control.length_notifier_plugin_data - actions_hbox = chat_control.xml.get_object('hbox') - actions_hbox.remove(d['counter']) - - tv = chat_control.msg_textview - tv.get_buffer().disconnect(d['h_id']) - if d['prev_color']: - tv.override_background_color(Gtk.StateType.NORMAL, - d['prev_color']) - except AttributeError: - pass - - @log_calls('LengthNotifierPlugin') - def jid_is_ok(self, jid): - if jid in self.config['JIDS'] or not self.config['JIDS']: - return True - - return False - - -class LengthNotifierPluginConfigDialog(GajimPluginConfigDialog): - def init(self): - self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path( - 'config_dialog.ui') - self.xml = Gtk.Builder() - self.xml.set_translation_domain('gajim_plugins') - self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH, - ['length_notifier_config_table']) - self.config_table = self.xml.get_object('length_notifier_config_table') - self.get_child().pack_start(self.config_table, False, False, 0) - - self.message_length_spinbutton = self.xml.get_object( - 'message_length_spinbutton') - self.message_length_spinbutton.get_adjustment().configure(140, 0, 500, - 1, 10, 0) - self.notification_colorbutton = self.xml.get_object( - 'notification_colorbutton') - self.jids_entry = self.xml.get_object('jids_entry') - - self.xml.connect_signals(self) - - def on_run(self): - self.message_length_spinbutton.set_value(self.plugin.config[ - 'MESSAGE_WARNING_LENGTH']) - color = Gdk.Color.parse(self.plugin.config['WARNING_COLOR'])[1] - self.notification_colorbutton.set_color(color) - #self.jids_entry.set_text(self.plugin.config['JIDS']) - self.jids_entry.set_text(','.join(self.plugin.config['JIDS'])) - - @log_calls('LengthNotifierPluginConfigDialog') - def on_message_length_spinbutton_value_changed(self, spinbutton): - self.plugin.config['MESSAGE_WARNING_LENGTH'] = spinbutton.get_value() - - @log_calls('LengthNotifierPluginConfigDialog') - def on_notification_colorbutton_color_set(self, colorbutton): - self.plugin.config['WARNING_COLOR'] = colorbutton.get_color().\ - to_string() - - @log_calls('LengthNotifierPluginConfigDialog') - def on_jids_entry_changed(self, entry): - text = entry.get_text() - if len(text) > 0: - self.plugin.config['JIDS'] = entry.get_text().split(',') + self._context.remove_class('length-warning') else: - self.plugin.config['JIDS'] = [] + self._set_count('0') + self._context.remove_class('length-warning') - @log_calls('LengthNotifierPluginConfigDialog') - def on_jids_entry_editing_done(self, entry): - pass + def _set_count(self, count): + self.set_label(str(count)) + + def update_settings(self, new_config): + self._max_length = new_config['MESSAGE_WARNING_LENGTH'] + self._color = new_config['WARNING_COLOR'] + self._set_css() + self._text_changed()