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