[length_notifier] Rework plugin

This commit is contained in:
Daniel Brötzmann
2020-01-19 00:20:50 +01:00
parent f1b3d2ea62
commit 452ec69735
3 changed files with 196 additions and 269 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
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)

View File

@@ -1,111 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkGrid" id="length_notifier_config_table">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Background color of the text entry when the specified message length is exceeded</property>
<property name="halign">center</property>
<property name="border_width">18</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Message Length</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="message_length_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Message length for the notification to be shown (set to 0 to disable color notification)</property>
<property name="halign">start</property>
<property name="width_chars">6</property>
<property name="input_purpose">number</property>
<property name="snap_to_ticks">True</property>
<property name="numeric">True</property>
<signal name="value-changed" handler="on_message_length_spinbutton_value_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Notification Color</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkColorButton" id="notification_colorbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Background color of the message input when the specified message length is reached</property>
<property name="halign">start</property>
<property name="title" translatable="yes">Pick a color for notification</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">XMPP Addresses</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="jids_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Restrict this plugin to certain contacts, e.g. to one microblogging bot (use comma without space as separator)</property>
<property name="halign">start</property>
<property name="placeholder_text" translatable="yes">user@example.org</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,19 +1,19 @@
# -*- coding: utf-8 -*- # -*- 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
## it under the terms of the GNU General Public License as published # it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only. # by the Free Software Foundation; version 3 only.
## #
## Gajim is distributed in the hope that it will be useful, # Gajim is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details. # GNU General Public License for more details.
## #
## You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
## along with Gajim. If not, see <http://www.gnu.org/licenses/>. # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
## #
''' '''
Message length notifier plugin. Message length notifier plugin.
@@ -23,173 +23,131 @@ 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
''' '''
import logging
from functools import partial
from gi.repository import Gtk from gi.repository import Gtk
from gi.repository import Gdk
from gajim.plugins import GajimPlugin 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 gajim.plugins.plugins_i18n import _
from length_notifier.config_dialog import LengthNotifierConfigDialog
log = logging.getLogger('gajim.p.length_notifier')
class LengthNotifierPlugin(GajimPlugin): class LengthNotifierPlugin(GajimPlugin):
@log_calls('LengthNotifierPlugin')
def init(self): def init(self):
self.description = _('Highlights message entry field in chat window ' self.description = _('Highlights the chat windows message input if '
'when given length of message is exceeded.') 'a specified message length is exceeded.')
self.config_dialog = LengthNotifierPluginConfigDialog(self)
self.config_dialog = partial(LengthNotifierConfigDialog, self)
self.gui_extension_points = { self.gui_extension_points = {
'chat_control_base': ( 'chat_control_base': (
self.connect_with_chat_control, self._on_connect_chat_control,
self.disconnect_from_chat_control) self._on_disconnect_chat_control
)
} }
self.config_default_values = { self.config_default_values = {
'MESSAGE_WARNING_LENGTH' : (140, 'Message length at which notification is invoked.'), 'MESSAGE_WARNING_LENGTH': (
'WARNING_COLOR' : ('#F0DB3E', 'Background color of text entry field in chat window when notification is invoked.'), 140,
'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 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') self._counters = {}
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
@log_calls('LengthNotifierPlugin') def _on_connect_chat_control(self, chat_control):
def connect_with_chat_control(self, chat_control):
jid = chat_control.contact.jid 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') 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) actions_hbox.pack_start(counter, False, False, 0)
counter.show()
d = {'prev_color' : None} def _on_disconnect_chat_control(self, chat_control):
tv = chat_control.msg_textview counter = self._counters.get(chat_control.control_id)
tb = tv.get_buffer() if counter is not None:
h_id = tb.connect('changed', self.textview_length_warning, counter.destroy()
chat_control) self._counters.pop(chat_control.control_id, None)
d['h_id'] = h_id
d['counter'] = counter
if tv.has_text(): def _check_jid(self, jid):
t = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True) allowed_jids = []
len_t = len(t) if len(self.config['JIDS']) > 0:
counter.set_text(str(len_t)) allowed_jids = self.config['JIDS'].split(',')
warning_length = self.config['MESSAGE_WARNING_LENGTH']
if len_t > warning_length and warning_length != 0: jid_allowed = jid in allowed_jids or not self.config['JIDS']
context = tv.get_style_context() if not jid_allowed:
d['prev_color'] = context.get_background_color( log.debug('No counter for JID %s' % jid)
Gtk.StateFlags.NORMAL) return jid_allowed
color = Gdk.RGBA()
Gdk.RGBA.parse(color, self.config['WARNING_COLOR']) def update_settings(self):
tv.override_background_color(Gtk.StateType.NORMAL, color) 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: else:
counter.set_text('0') self._context.remove_class('length-warning')
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(',')
else: else:
self.plugin.config['JIDS'] = [] self._set_count('0')
self._context.remove_class('length-warning')
@log_calls('LengthNotifierPluginConfigDialog') def _set_count(self, count):
def on_jids_entry_editing_done(self, entry): self.set_label(str(count))
pass
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()