Commit 27086dde authored by Evert Mouw's avatar Evert Mouw

Update psychic/config_dialog.ui, psychic/icon.readme, psychic/__init__.py,...

Update psychic/config_dialog.ui, psychic/icon.readme, psychic/__init__.py, psychic/manifest.ini, psychic/psychic.py, psychic/psychic.png files
parent d9b146ee
from .psychic import PsychicModePlugin
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="psychic_prefs">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Psychic Mode Configuration</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkPaned">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkImage" id="psychic_buuf">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixbuf">psychic.png</property>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">True</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="title_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Psychic Mode</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="2"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="info_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="label" translatable="yes">Actions to perform ahead of receiving a message, when one of your contacts is composing a message to you.
The icon on the left was created by Mattahan (2011) as part of the BuuF Halloween Extravaganza iconset, free for non-commercial use. The original name of the icon was Word up, peace incarcerated scarfaces.</property>
<property name="wrap">True</property>
<property name="width_chars">38</property>
<property name="max_width_chars">42</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="notification_label">
<property name="can_focus">False</property>
<property name="label" translatable="yes">Notify me using the desktop notifier</property>
<property name="justify">right</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="notification_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="active">True</property>
<signal name="state-set" handler="notification_value_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="window_open_ahead_label">
<property name="can_focus">False</property>
<property name="label" translatable="yes">Open a new chat window</property>
<property name="justify">right</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="window_open_ahead_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="state-set" handler="window_open_ahead_value_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="window_open_existing_label">
<property name="can_focus">False</property>
<property name="label" translatable="yes">Activate an already open chat window</property>
<property name="justify">right</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="window_open_existing_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="state-set" handler="window_open_existing_value_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Source of the nice icon:
iconset "BuuF Halloween Extravaganza"
created by Paul Davey (Mattahan)
https://www.deviantart.com/mattahan/
https://mattahan.tumblr.com/
mattahan@gmail.com
original file: Word up, peace incarcerated scarfaces.png
renamed to: psychic.png
LICENCE
free for non-commercial use
mattahan Nov 4, 2011 Professional Digital Artist
https://www.deviantart.com/mattahan/art/UltraBUUF-260792930
[info]
name: Psychic Mode
short_name: psychic
version: 0.0.1
description: Your humble Psychic warns for incoming messages even before they are sent.
You can choose to receive a notification, open a chat window in advance, or both.
It detects remote activity using chatstates (XEP-0085).
authors: Evert Mouw <post@evert.net>
homepage: https://dev.gajim.org/gajim/gajim-plugins/wikis/PsychicModePlugin
min_gajim_version: 1.0.99
max_gajim_version: 1.1.90
"""
Psychic Mode plugin for Gajim, by Evert Mouw <post@evert.net>
Psychic mode was inspired by
- Chat State Notifications in roster, by Denis Fomin <fominde@gmail.com>
- Psychic plugin for Pidgin (psychic.c), by Christopher O'Brien <siege@preoccupied.net>
Version history:
2019-04-09 first private alpha
"""
import unicodedata
import re
from gi.repository import GObject
from gi.repository import Gtk
from gajim.plugins import GajimPlugin
from gajim.plugins.helpers import log_calls
from gajim.plugins.gui import GajimPluginConfigDialog
from gajim.common import ged
from gajim.common import app
from gajim.common import helpers
from gajim import gtkgui_helpers
from gajim import notify
# Since Gajim 1.1.0 _() has to be imported
try:
from gajim.common.i18n import _
except ImportError:
pass
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':
return '\u200E'
elif bidi == 'AL' or bidi == 'R':
return '\u200F'
return '\u200E'
class PsychicModePlugin(GajimPlugin):
@log_calls('PsychicModePlugin')
def init(self):
self.description = _('Your humble Psychic warns for incoming messages even before they are sent.\n'
'You can choose to receive a notification, open a chat window in advance, or both.\n'
'It detects remote activity using chatstates (XEP-0085).')
self.config_dialog = PsychicModePluginConfigDialog(self)
# It seems that the "chatstate-received" event as documented for plugins at
# https://dev.gajim.org/gajim/gajim/wikis/development/pluginsevents
# does not !! match with the object as pushed as event in chatstates.py
# Workaround: use the contact object which is part of the event. ~Evert
#
# According to the wiki:
# Event { chatstate-received } --> Attributes { msg_obj, stanza, jid, fjid, resource, chatstate }
#
# From modules/chatstates.py ::
# app.nec.push_outgoing_event( NetworkEvent('chatstate-received', account=self._account, contact=contact) )
#
# The contact is created using: contact = app.contacts.get_gc_contact
# Which is defined in contacts.py as class GC_Contact(CommonContact) with
# Properties = { jid, account, resource, show, status, name, chatstate, room_jid }
# And also interesting methods = { get_shown_name, get_full_jid, ... }
#
self.events_handlers = {'chatstate-received': (ged.GUI2, self.chatstate_received), }
self.active = None
def chatstate_received(self, EventObject):
if not self.active:
return
# Receive EventObject and stop on some conditions
try:
contact = EventObject.contact
except:
return
if not contact:
return
try:
groupchat = room_jid
except:
groupchat = False
else:
groupchat = True
if groupchat:
return
chatstate = contact.chatstate
valid_chatstates = [ 'active', 'composing', 'inactive', 'paused', 'gone' ]
if chatstate not in valid_chatstates:
return
# From the Psychic plugin for Pidgin (psychic.c):
# This is a quote from Star Wars. You should probably not translate it
# literally. If you can't find a fitting cultural reference in your
# language, consider translating something like this instead:
# "You feel a new message coming."
psychic_message = _('You feel a disturbance in the force...')
# If no already opened chat window;
# - optionally give a notification
# - optionally create a chat window
# If a chat window is already opened;
# - give no notification
# - optionally activate the chat window
chatwindow_open = False
chat_control = app.interface.msg_win_mgr.get_control(contact.jid, EventObject.account)
if chat_control:
chatwindow_open = True
if chatstate == 'composing':
if self.config['notification'] and chatwindow_open == False:
warning = "Watch out for " + contact.name
popup = notify.PopupNotificationWindow("Contact Changed Status", contact.jid,
EventObject.account, title=psychic_message, text=warning, timeout=5)
if self.config['window_open_ahead'] and (not chat_control):
# open a new chat window
app.interface.new_chat(contact, EventObject.account)
if self.config['window_open_existing'] and (chat_control):
# activate the chat window
chat_control.parent_win.set_active_tab(chat_control)
@log_calls('PsychicModePlugin')
def activate(self):
try:
# read from persistent config
alreadystored = self.config['notification']
alreadystored = self.config['window_open_ahead']
alreadystored = self.config['window_open_existing']
except:
# load default values and store them
self.config['notification'] = True
self.config['window_open_ahead'] = False
self.config['window_open_existing'] = False
self.active = True
@log_calls('PsychicModePlugin')
def deactivate(self):
self.active = False
class PsychicModePluginConfigDialog(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, ['vbox1'])
# for use by on_run
self.notification = self.xml.get_object('notification_switch')
self.window_open_ahead = self.xml.get_object('window_open_ahead_switch')
self.window_open_existing = self.xml.get_object('window_open_existing_switch')
vbox = self.xml.get_object('vbox1')
self.get_child().pack_start(vbox, True, True, 0)
self.xml.connect_signals(self)
# when dialog loaded
def on_run(self):
self.notification.set_active(self.plugin.config['notification'])
self.window_open_ahead.set_active(self.plugin.config['window_open_ahead'])
self.window_open_existing.set_active(self.plugin.config['window_open_existing'])
# signal handlers
def notification_value_changed(self, notification_switch, dummy):
self.plugin.config['notification'] = bool(notification_switch.get_active())
def window_open_ahead_value_changed(self, window_open_ahead_switch, dummy):
self.plugin.config['window_open_ahead'] = bool(window_open_ahead_switch.get_active())
def window_open_existing_value_changed(self, window_open_existing_switch, dummy):
self.plugin.config['window_open_existing'] = bool(window_open_existing_switch.get_active())
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment