appindicator_integration/ 0000755 0001755 0001755 00000000000 13751571240 015675 5 ustar debacle debacle appindicator_integration/org.gajim.Gajim.Plugin.appindicator.metainfo.xml 0000644 0001755 0001755 00000000751 13751571240 027037 0 ustar debacle debacle
org.gajim.Gajim.Plugin.appindicator
org.gajim.Gajim
Ayatana Appindicator integration plugin
Integrate Gajim with the Ayatana AppIndicator
https://gajim.org/
CC-BY-SA-3.0
GPL-3.0
gajim-devel_AT_gajim.org
appindicator_integration/appindicator_integration.png 0000644 0001755 0001755 00000001666 13751571240 023474 0 ustar debacle debacle PNG
IHDR a sBIT|d pHYs + tEXtSoftware www.inkscape.org< tEXtAuthor Josef Vybíralx tEXtCreation Time 28.10.2006H/+ tEXtSource http://cornelius.gimp.cz'Z IDAT8oTu?7:7mB:DT҅%!&ƅqeaG
$Ƥ&@
?tZ-t:N͛y.Or67{s5p+2'OQqs[o]K`R_(Qo|+~Ͷzg >$>,rp̫i> kts3)V!IU~:@QQcM4, ޣmnĉ/Uc1il4`
R~^<@$5$7>nfnk[*4D%)wr~r5:zE3-̶FjWy='_mO\).v{wc,Fw8W8L:swRdNhĩK'ogЇ2,xi`o667&B9qcÖ0"^%{[:v=[:
xPU5wrF1V`Յ((A3[GZt56o
r|\a"G/(_+T(5zw&Q`hӈ5i?'ccOued}"|J"k6=MT{sb+tj{YK2} IENDB` appindicator_integration/__init__.py 0000644 0001755 0001755 00000000062 13751571240 020004 0 ustar debacle debacle from .plugin import AppindicatorIntegrationPlugin
appindicator_integration/manifest.ini 0000644 0001755 0001755 00000000706 13751571240 020207 0 ustar debacle debacle [info]
name: Ayatana Appindicator integration
short_name: appindicator_integration
version: 1.3.3
description: This plugin integrates Gajim with the Ayatana AppIndicator. You must have libappindicator3 installed to enable this plugin.
homepage: https://dev.gajim.org/gajim/gajim-plugins/wikis/AppindicatorSupportPlugin
authors: Denis Borenko
Philipp Hörist
min_gajim_version: 1.2.91
max_gajim_version: 1.3.90
appindicator_integration/plugin.py 0000644 0001755 0001755 00000020042 13751571240 017543 0 ustar debacle debacle # -*- coding: utf-8 -*-
"""
Appindicator integration plugin.
Rewritten from Ubuntu Ayatana Integration plugin
2013 Denis Borenko
2017 Philipp Hörist
:license: GPLv3
"""
import time
import gi
from gi.repository import Gtk, GLib, Gdk
try:
gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as appindicator
HAS_ERROR = False
except (ValueError, ImportError):
try:
gi.require_version('AyatanaAppIndicator3', '0.1')
from gi.repository import AyatanaAppIndicator3 as appindicator
HAS_ERROR = False
except (ValueError, ImportError):
HAS_ERROR = True
from gajim.common import app, ged
from gajim.common import configpaths
from gajim.plugins import GajimPlugin
from gajim.plugins.helpers import log_calls
from gajim.plugins.plugins_i18n import _
class AppindicatorIntegrationPlugin(GajimPlugin):
@log_calls("AppindicatorIntegrationPlugin")
def init(self):
self.description = _('This plugin integrates Gajim with the Ayatana '
'AppIndicator.')
self.config_dialog = None
if HAS_ERROR:
self.activatable = False
self.available_text += _('Please install libappindicator3')
return
self.events_handlers = {'our-show': (ged.GUI2,
self.set_indicator_icon)}
self.windowstate = None
@log_calls("AppindicatorIntegrationPlugin")
def activate(self):
self.events = {}
self.online_icon = 'org.gajim.Gajim'
self.offline_icon = 'org.gajim.Gajim-symbolic'
self.connected = 0
self.connect_menu_item = Gtk.MenuItem(label=_('Connect'))
self.connect_menu_item.connect("activate", self.connect)
self.show_gajim_menu_item = Gtk.MenuItem(
label=_('Show/hide contact list'))
self.show_gajim_menu_item.connect("activate", self.roster_raise)
self.show_gajim_menu_item.show()
self.event_separator = Gtk.SeparatorMenuItem()
self.menuEventInsertIndex = 3
itemExitSeparator = Gtk.SeparatorMenuItem()
itemExitSeparator.show()
itemExit = Gtk.MenuItem(label=_('Quit'))
itemExit.connect("activate", self.on_exit_menuitem_activate)
itemExit.show()
self.menu = Gtk.Menu()
self.menu.append(self.connect_menu_item)
self.menu.append(self.show_gajim_menu_item)
self.menu.append(self.event_separator)
self.menu.append(itemExitSeparator)
self.menu.append(itemExit)
self.menu.show()
self.indicator = appindicator.Indicator.new(
'Gajim', self.offline_icon,
appindicator.IndicatorCategory.COMMUNICATIONS)
self.indicator.set_icon_theme_path(str(configpaths.get('ICONS')))
self.indicator.set_attention_icon_full('mail-unread', 'New Message')
self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
self.indicator.set_menu(self.menu)
self.set_indicator_icon()
app.events.event_added_subscribe(self.on_event_added)
app.events.event_removed_subscribe(self.on_event_removed)
self.roster = app.interface.roster.window
self.handlerid = self.roster.connect('window-state-event',
self.window_state_event_cb)
def connect(self, widget, data=None):
for account in app.connections:
if app.settings.get_account_setting(account,
'sync_with_global_status'):
app.connections[account].change_status('online',
'online')
def window_state_event_cb(self, win, event):
if event.new_window_state & Gdk.WindowState.ICONIFIED:
self.windowstate = 'iconified'
elif event.new_window_state & Gdk.WindowState.WITHDRAWN:
self.windowstate = 'hidden'
def set_indicator_icon(self, *args):
is_connected = 0
for account in app.connections:
if not app.settings.get_account_setting(account,
'sync_with_global_status'):
continue
if app.account_is_connected(account):
is_connected = 1
break
if self.connected != is_connected:
self.connected = is_connected
if self.connected == 1:
self.indicator.set_icon_full(self.online_icon, _('Online'))
self.connect_menu_item.hide()
else:
self.indicator.set_icon_full(self.offline_icon, _('Offline'))
self.connect_menu_item.show()
@log_calls("AppindicatorPlugin")
def deactivate(self):
app.events.event_added_unsubscribe(self.on_event_added)
app.events.event_removed_unsubscribe(self.on_event_removed)
if hasattr(self, 'indicator'):
self.indicator.set_status(appindicator.IndicatorStatus.PASSIVE)
del self.indicator
self.roster.disconnect(self.handlerid)
def roster_raise(self, widget, data=None):
win = app.interface.roster.window
if win.get_property("visible") and self.windowstate != 'iconified':
GLib.idle_add(win.hide)
else:
win.present()
self.windowstate = 'shown'
def on_exit_menuitem_activate(self, widget, data=None):
app.interface.roster.on_quit_request()
def event_raise(self, widget, event):
app.interface.handle_event(event.account, event.jid, event.type_)
win = app.interface.roster.window
if not win.is_active():
win.present()
def on_event_added(self, event):
account = event.account
jid = event.jid
when = time.time()
contact = ""
key = (account, jid)
events = ['chat', 'printed_chat', 'printed_normal',
'normal', 'file-request', 'jingle-incoming']
if event.type_ in events:
contact = app.contacts.get_contact_from_full_jid(account, jid)
if contact:
contact = contact.get_shown_name()
else:
contact = jid
elif event.type_ == "pm" or event.type_ == "printed_pm":
contact = app.get_nick_from_jid(app.get_room_from_fjid(jid)) + \
"/" + app.get_room_and_nick_from_fjid(jid)[1]
elif event.type_ == "printed_marked_gc_msg":
contact = app.get_nick_from_jid(app.get_room_from_fjid(jid))
else:
return
event.time = when
if key not in self.events:
item = Gtk.MenuItem(label=contact + " (1)")
item.connect("activate", self.event_raise, event)
item.show()
self.menu.insert(item, self.menuEventInsertIndex)
self.event_separator.show()
self.events[key] = {}
self.events[key]['item'] = item
self.events[key]['contact'] = contact
self.events[key]['events'] = [event]
else:
self.events[key]['events'].append(event)
item = self.events[key]['item']
item.set_label(self.events[key]['contact'] +
" (" + str(len(self.events[key]['events'])) + ")")
self.indicator.set_status(appindicator.IndicatorStatus.ATTENTION)
def on_event_removed(self, events):
for event in events:
key = (event.account, event.jid)
if key in self.events and event in self.events[key]['events']:
self.events[key]['events'].remove(event)
if len(self.events[key]['events']) == 0: # remove indicator
self.menu.remove(self.events[key]['item'])
del self.events[key]
else:
self.events[key]['item'].connect("activate",
self.event_raise, self.events[key]['events'][-1])
if len(self.events) == 0:
self.event_separator.hide()
self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)