diff options
author | Philipp Hörist <forenjunkie@chello.at> | 2017-10-09 00:21:59 +0300 |
---|---|---|
committer | Philipp Hörist <forenjunkie@chello.at> | 2017-10-09 00:21:59 +0300 |
commit | 786efee2e57907b405250b229596a20aac22af23 (patch) | |
tree | 16312206f7d1e87571641f878838390d6e40021c | |
parent | 6a7be8788924ef05e81b9b4794321b29c22f6097 (diff) | |
parent | c8e8f1a8b73e79fcdf1de2abd794d3bcb277556b (diff) |
Merge branch 'gtk3' into 'gtk3'
Port Appindicator Plugin
See merge request !45
-rw-r--r-- | appindicator_integration/__init__.py | 1 | ||||
-rw-r--r-- | appindicator_integration/manifest.ini | 10 | ||||
-rw-r--r-- | appindicator_integration/plugin.py | 215 |
3 files changed, 226 insertions, 0 deletions
diff --git a/appindicator_integration/__init__.py b/appindicator_integration/__init__.py new file mode 100644 index 0000000..25139d2 --- /dev/null +++ b/appindicator_integration/__init__.py @@ -0,0 +1 @@ +from .plugin import AppindicatorIntegrationPlugin diff --git a/appindicator_integration/manifest.ini b/appindicator_integration/manifest.ini new file mode 100644 index 0000000..fd18c25 --- /dev/null +++ b/appindicator_integration/manifest.ini @@ -0,0 +1,10 @@ +[info] +name: Appindicator integration +short_name: appindicator_integration +version: 1.0.0 +description: This plugin integrates Gajim with the appindicator. You must have gir1.2-appindicator3-0.1 installed to enable this plugin.<br/> + Rewriten from Ubuntu Ayatana Integration plugin +homepage: https://dev.gajim.org/gajim/gajim-plugins/wikis/AppindicatorSupportPlugin +authors: Denis Borenko <borenko@rambler.ru> + Philipp Hörist <philipp@hoerist.com> +min_gajim_version: 0.16.11 diff --git a/appindicator_integration/plugin.py b/appindicator_integration/plugin.py new file mode 100644 index 0000000..92cd25f --- /dev/null +++ b/appindicator_integration/plugin.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +""" +Appindicator integration plugin. + +Rewriten from Ubuntu Ayatana Integration plugin +2013 Denis Borenko <borenko@rambler.ru> +2017 Philipp Hörist <philipp@hoerist.com> +:license: GPLv3 +""" + +import os +import time + +import gi +gi.require_version('AppIndicator3', '0.1') +from gi.repository import AppIndicator3 as appindicator +from gi.repository import Gtk, GLib, Gdk + +# Gajim +from gajim.common import app, ged +from gajim.plugins import GajimPlugin +from gajim.plugins.gajimplugin import GajimPluginException +from gajim.plugins.helpers import log_calls +from gajim import gtkgui_helpers + + +class AppindicatorIntegrationPlugin(GajimPlugin): + + @log_calls("AppindicatorIntegrationPlugin") + def init(self): + #if ERRORMSG: + # self.activatable = False + # self.available_text += _(ERRORMSG) + # return + #else: + self.config_dialog = None + self.events_handlers = {'our-show': (ged.GUI2, + self.set_indicator_icon)} + self.windowstate = None + + @log_calls("AppindicatorIntegrationPlugin") + def activate(self): + + self.events = {} + + self.attention_icon = "tray-message" + self.online_icon = "tray-online" + self.offline_icon = "tray-offline" + self.connected = 0 + + self.connect_menu_item = Gtk.MenuItem('Connect') + self.connect_menu_item.connect("activate", self.connect) + + self.show_gajim_menu_item = Gtk.MenuItem('Show/hide roster') + 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('Exit') + 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.APPLICATION_STATUS) + self.indicator.set_attention_icon(self.attention_icon) + 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.config.get_per('accounts', 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, obj=''): + is_connected = 0 + for account in app.connections: + if not app.config.get_per('accounts', 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(self.online_icon) + self.connect_menu_item.hide() + else: + self.indicator.set_icon(self.offline_icon) + 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: + icon = None + if app.config.get("show_avatars_in_roster"): + pix = app.contacts.get_avatar(account, jid, size=16) + icon = Gtk.Image() + icon.set_from_pixbuf(pix) + item = Gtk.ImageMenuItem(contact + " (1)") + if icon: + item.set_image(icon) + item.set_always_show_image(True) + 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) |