1# -*- coding: utf-8 -*-
2#
3# Gtk Status Icon (gPodder bug 1495)
4# Thomas Perl <thp@gpodder.org>; 2012-07-31
5#
6
7import logging
8import os.path
9
10from gi.repository import GdkPixbuf, Gtk
11
12import gpodder
13from gpodder.gtkui import draw
14
15logger = logging.getLogger(__name__)
16
17_ = gpodder.gettext
18
19__title__ = _('Gtk Status Icon')
20__description__ = _('Show a status icon for Gtk-based Desktops.')
21__category__ = 'desktop-integration'
22__only_for__ = 'gtk'
23__disable_in__ = 'unity,win32'
24
25DefaultConfig = {
26    'download_progress_bar': False,  # draw progress bar on icon while downloading?
27}
28
29
30class gPodderExtension:
31    def __init__(self, container):
32        self.container = container
33        self.config = self.container.config
34        self.status_icon = None
35        self.icon_name = None
36        self.gpodder = None
37        self.last_progress = 1
38
39    def set_icon(self, use_pixbuf=False):
40        path = os.path.join(os.path.dirname(__file__), '..', '..', 'icons')
41        icon_path = os.path.abspath(path)
42
43        theme = Gtk.IconTheme.get_default()
44        theme.append_search_path(icon_path)
45
46        if self.icon_name is None:
47            if theme.has_icon('gpodder'):
48                self.icon_name = 'gpodder'
49            else:
50                self.icon_name = 'stock_mic'
51
52        if self.status_icon is None:
53            self.status_icon = Gtk.StatusIcon.new_from_icon_name(self.icon_name)
54            return
55
56        # If current mode matches desired mode, nothing to do.
57        is_pixbuf = (self.status_icon.get_storage_type() == Gtk.ImageType.PIXBUF)
58        if is_pixbuf == use_pixbuf:
59            return
60
61        if not use_pixbuf:
62            self.status_icon.set_from_icon_name(self.icon_name)
63        else:
64            # Currently icon is not a pixbuf => was loaded by name, at which
65            # point size was automatically determined.
66            icon_size = self.status_icon.get_size()
67            icon_pixbuf = theme.load_icon(self.icon_name, icon_size, Gtk.IconLookupFlags.USE_BUILTIN)
68            self.status_icon.set_from_pixbuf(icon_pixbuf)
69
70    def on_load(self):
71        self.set_icon()
72        self.status_icon.connect('activate', self.on_toggle_visible)
73        self.status_icon.set_has_tooltip(True)
74        self.status_icon.set_tooltip_text("gPodder")
75
76    def on_toggle_visible(self, status_icon):
77        if self.gpodder is None:
78            return
79
80        visibility = self.gpodder.main_window.get_visible()
81        self.gpodder.main_window.set_visible(not visibility)
82
83    def on_unload(self):
84        if self.status_icon is not None:
85            self.status_icon.set_visible(False)
86            self.status_icon = None
87            self.icon_name = None
88
89    def on_ui_object_available(self, name, ui_object):
90        if name == 'gpodder-gtk':
91            self.gpodder = ui_object
92
93    def get_icon_pixbuf(self):
94        assert self.status_icon is not None
95        if self.status_icon.get_storage_type() != Gtk.ImageType.PIXBUF:
96            self.set_icon(use_pixbuf=True)
97        return self.status_icon.get_pixbuf()
98
99    def on_download_progress(self, progress):
100        logger.debug("download progress: %f", progress)
101
102        if not self.config.download_progress_bar:
103            # reset the icon in case option was turned off during download
104            if self.last_progress < 1:
105                self.last_progress = 1
106                self.set_icon()
107            # in any case, we're now done
108            return
109
110        if progress == 1:
111            self.set_icon()  # no progress bar
112            self.last_progress = progress
113            return
114
115        # Only update in 3-percent-steps to save some resources
116        if abs(progress - self.last_progress) < 0.03 and progress > self.last_progress:
117            return
118
119        icon = self.get_icon_pixbuf().copy()
120        progressbar = draw.progressbar_pixbuf(icon.get_width(), icon.get_height(), progress)
121        progressbar.composite(icon, 0, 0, icon.get_width(), icon.get_height(), 0, 0, 1, 1, GdkPixbuf.InterpType.NEAREST, 255)
122
123        self.status_icon.set_from_pixbuf(icon)
124        self.last_progress = progress
125